Ashley Duncan
Ashley Duncan

Reputation: 1019

C++ Preprocessor Stringize - Different between GCC and MSVC

With the following example, the output is different between MSVC and GCC. Can someone please point me in the right direction to understand why?

#define TO_STRING(...) #__VA_ARGS__
#define QUOTE(...) TO_STRING(__VA_ARGS__)

#define KEY1 "Key1"
#define KEY2 "Key2"
#define KEY3 "Key3"
#define LEN1 32
#define LEN2 32


const char * cNVKeysMetaData = QUOTE(
{
    "Area1":[ 
        {
            "key":KEY1,
            "maxLength":LEN1,
            "type":"s",
            "default":"Hello"
        },
#if defined(TEST)
        {
            "key":KEY2,
            "maxLength":LEN2,
            "type":"s",
            "default":"invalid"
        },
#endif
        {
            "key":KEY3,
            "maxLength":64,
            "type":"s",
            "default":"invalid"
        }
    ]
}
);

#include <iostream>

int main()
{
    std::cout << cNVKeysMetaData << std::endl;
    return 0;
}

GCC Output:

{ "Area1":[ { "key":"Key1", "maxLength":32, "type":"s", "default":"Hello" }, { "key":"Key3", "maxLength":64, "type":"s", "default":"invalid" } ] }

MSVC Output:

{ "Area1":[ { "key":"Key1", "maxLength":32, "type":"s", "default":"Hello" }, #if defined(TEST) { "key":"Key2", "maxLength":32, "type":"s", "default":"invalid" }, #endif { "key":"Key3", "maxLength":64, "type":"s", "default":"invalid" } ] }

Note that MSVC does replace the macros KEY1 etc, but does not strip out the #if. GCC does strip out the #if.

Upvotes: 1

Views: 132

Answers (1)

KamilCuk
KamilCuk

Reputation: 141000

According to C/C++: How should preprocessor directive work on macros argument list? , you can't put preprocessor directives (like #if) inside macro argument lists. The behavior of your code is undefined.

I think I would do:

#ifdef TEST
#define IF_TEST(...) __VA_ARGS__
#else
#define IF_TEST(...)
#endif

QUOTE(
 ....
 IF_TEST(
        {
            "key":KEY2,
            "maxLength":LEN2,
            "type":"s",
            "default":"invalid"
        },
  )
  ...
)

Upvotes: 2

Related Questions