warwolf
warwolf

Reputation: 75

Explicit C++ Macro Expansion

I want to make all logging functions include the file and line, thus I need a macro for it. The macro is defined in the following manner:

 inline void _internLogFunc(int line, const char* function, const char* data ...)
    {...}

    #define _InternLogParams(...) _internLogFunc(__LINE__, __FUNC__, __VA_ARGS__)

    #define Log(...) _InternLogParams(__VA_ARGS__)

The problem is that when the function is called in the following manner:

 Log("[Version]: "
    #if defined(_RELEASE)
                "RELEASE "
    #elif defined(_PROFILE)
                "PROFILE "
    #else
                "DEBUG "
    #endif

    #if defined(PURE_CLIENT)
                "PURE CLIENT"
    #elif (DEDICATED_SERVER)
                "DEDICATED SERVER"
    #else
                "DEVELOPMENT BUILD"
    #endif
                );

The macros expand to the following:

> _internLogFunc(950,  
>                __FUNCTION__  , 
>                "[Version]: " 
>                #if defined(_RELEASE) "RELEASE "
>                #elif defined(_PROFILE) "PROFILE " 
>                #else "DEBUG " 
>                #endif 
>                #if defined(PURE_CLIENT) "PURE CLIENT" 
>                #elif (DEDICATED_SERVER) "DEDICATED SERVER" 
>                #else "DEVELOPMENT BUILD" 
>                #endif);

Does anyone have any idea how I could make the macros given as argument expand first?

Upvotes: 1

Views: 417

Answers (2)

hansmuff
hansmuff

Reputation: 42

Your Log(...) macro takes variable arguments, and the call to it is parsed by the pre-processor. It'll take everything it sees in the braces and pass it as a VA_ARG.

I suspect it might be a limitation of using the ellipsis in the pre-processor.

Write the Log() function in C++ to avoid the pre-processor parsing that way, or use macros outside of the Log() call to build the string you want to output.

For instance:

#if defined(_RELEASE)
#define DS1 "RELEASE "    
#elif defined(_PROFILE)
#define DS1 "PROFILE "
#else
#define DS1 "DEBUG "
#endif

#if defined(PURE_CLIENT)
#define DS2 "PURE CLIENT"
#elif defined (DEDICATED_SERVbER)
#define DS2 "DEDICATED SERVER"
#else
#define DS2 "DEVELOPMENT BUILD"
#endif

#define DEBUG_STRING "[Version]: " DS1 DS2


Log(DEBUG_STRING, "Extra1", "extra2");

Upvotes: 1

Yuri
Yuri

Reputation: 351

just put all the #ifedfs outside the function call and use them to define some literal strings. Example:

#ifdef _RELEASE 
#define VERSION "RELEASE"
#else 
#define VERSION "DEBUG"
#endif

...

LOG(VERSION);    

...

Upvotes: 4

Related Questions