Aaron Stackpole
Aaron Stackpole

Reputation: 53

Preprocessor Macro Translation

In the .NET Core CLR source code, I found the following macro definition:

#define CORECLR_HOSTING_API(function, ...) \
  extern "C" int function(__VA_ARGS__); \
  typedef int (*function##_ptr)(__VA_ARGS__)

CORECLR_HOSTING_API(coreclr_shutdown,
            void* hostHandle,
            unsigned int domainId);

The comments say that this defines a function prototype and a function pointer. Is anyone able to "translate" what the non-macro version of this would look like? That is to say, what would this look like if it was NOT wrapped in the macro? The "*function##_ptr" part is confusing me...

Upvotes: 0

Views: 317

Answers (2)

KamilCuk
KamilCuk

Reputation: 140880

Sometimes there are compiler options which allow to see the proprocessor output of statements. If not, there always is godbolt, in which you can use -E option with gcc compiler to see (newline added by me):

extern "C" int coreclr_shutdown(void* hostHandle, unsigned int domainId); 
typedef int (*coreclr_shutdown_ptr)(void* hostHandle, unsigned int domainId)

The ## in macro expansion means concatenation. So the function ## _ptr means to concatenate the string behind function (it's macro argument) with the string (literal) _ptr. It's typically for example to:

#define CONCAT(a,b) a ## b
CONCAT(abc, def) // will be translated by preprocessor into abcdef

Upvotes: 2

manveti
manveti

Reputation: 1711

The ## operator is concatenation, used here because function_ptr is a valid identifier, so the preprocessor wouldn't know to replace the function part of it. The result of preprocessing, then, is:

extern "C" int coreclr_shutdown(void* hostHandle, unsigned int domainId);
typedef int (*coreclr_shutdown_ptr)(void* hostHandle, unsigned int domainId);

(modulo whitespace changes I've made for readability)

Upvotes: 4

Related Questions