Reputation: 53
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
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
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