Search code examples
cc-preprocessorstringification

Asterisk in the argument name with C preprocessor


I want to implement cross-platform build of my DLL with mingw32/VC.
At the moment everything is perfect with mingw side. However I have to wrap several things in macro for VC (it is built as /TC), for example:

void __attribute__((fastcall)) do1 (  A*, B , C, D );
bool __attribute__((fastcall)) ( *do2 ) ( E*, F );

The first one is simple, just a macro:

#ifdef __MINGW32__
    #define __FASTCALL__ __attribute__((fastcall))
#elif _MSC_VER
    #define __FASTCALL__ __fastcall
#else
    #error "unsupported compiler"
#endif

The problem comes with the second one. Calling convention with a function pointer should looks like

bool ( __fastcall *do2 ) ( E*, F );

I tried the following macro (I skipped ifdef part):

#define __FASTCALLP__(func) (__attribute__((fastcall))(*##func))
#define __FASTCALLP__(func) (__fastcall *##func)

or if pass function name with asterisk:

#define __FASTCALLP__(func) (__attribute__((fastcall))(##func))
#define __FASTCALLP__(func) (__fastcall ##func)

Both failed with

error: pasting "*" and "function_name" does not give a valid preprocessing token

May I wrong at my approach at all? Or I have to ifdef the whole code blocks or separate it to different files?


Solution

  • The problem is with the Concatenation-Operator ##. It will produce a new preprocessor token by concatenating the left- and right-hand-side, which does not exists (*do2 is no defined token)

    Simply omit it and write like this (omitting #ifdefs):

    #define __FASTCALL__(func) (__attribute__((fastcall))(func))
    #define __FASTCALL__(func) (__fastcall func)
    

    and use like this:

    bool __FASTCALL__(do1)(A*, B , C, D);
    bool __FASTCALL__(*do2)(E*, F);