Friday, March 18, 2016

Export Makers, Symbol Visibility, …?

Leave a Comment

I am trying to develop a library which has to be platform independent. While writing library API, it is a good practice making some prefixes for the functions with the some preprocessor defines.

For example, Windows API has WINAPI, OpenMPI has OMPI_DECLSPEC and so on...

OpenMPI:

OMPI_DECLSPEC  int MPI_Init(int *argc, char ***argv); 

OpenGL:

GLAPI void GLAPIENTRY glBegin( GLenum mode ); 

With this preprocessor defines, programmers can set export options, visibilities, calling conventions for functions in the library. At OpenGL function declarations, as you can see, there are two different preprocessor defines.

What is the name of this prefix in the literature?

Edit: https://gcc.gnu.org/wiki/Visibility in this page, the topic is discussed. I think, this kind of macros deserves a special name. We could name it as "visibility macro" or something, but this macro can set other kind of things according to compiler, OS, etc...

2 Answers

Answers 1

What is the name of this prefix in the literature?

They are called macros. They facilitate conditional compilation in the C and C++ languages. They were also used as substitute for typedefs back in the days. Take GLAPIENTRY for instance, it's defined thus:

#define GLAPIENTRY __stdcall 

If the author has to change the calling convention to __cdecl, if __stdcall was directly put in the function declaration, then for every function this has to be changed. However, with the macro, just redefining would do:

#define GLAPIENTRY __cdecl 

Answers 2

As far as I know there isn't a specific name for these types of macros, but if I were to have to give these a name, I would have to label them "context macros" or (more specific to functions) "function attribute portability context macros" since they are typically defined based on the context of the compilation unit.

This could be further split into additional categories:

  • Portability macros for example:
    • __attribute__() vs. __declspec()
    • __attribute__((always_inline)) vs. __forceinline
    • or defining unsupported attributes as empty
  • Compilation context macros
    • static vs extern
    • visibility context macros (hidden, default, protected, internal/symbolic,...)

Portability context macros are used to overcome the differences between compilers and/or host/target architectures and operating systems. These cover more than just differences between visibility (including any special function attributes)

Compilation context macros can allow the same source to be used for effeciently compiling for different types of compilation such as a static vs PIC and library vs. binary. These may include various inline or visibility directives depending on the compilation context.

In the example given

GLAPI void GLAPIENTRY glBegin( GLenum mode ); 

The GLAPI would represent a compilation context (probably also with associated portability macros) and the GLAPIENTRY is just a portability macro wrapper for a specific set of function attributes (it is a "cross-platform" API).

If You Enjoyed This, Take 5 Seconds To Share It

0 comments:

Post a Comment