c++visual-studioc++20visual-studio-2022variadic-macros

Getting __VA_OPT__ to be recognized by Visual Studio?


Tried to set /std:c++20 or /std:c++latest along /Zc:preprocessor as mentioned in the documentation but Visual Studio refuses to recognize __VA_OPT__ in the following snippet:

#define _sdk_log(fmt, ...) \
    printf(fmt __VA_OPT__(,) __VA_ARGS__)
#endif

Since the keyword isn't recognized, every place this macro is used errors like this:

Error C2146 syntax error: missing ')' before identifier 'VA_OPT'

Question:

How can I get Visual Studio to recognize __VA_OPT__?


Solution

  • Unfortunately __VA_OPT__ support in MSVC is broken in some versions of Visual Studio.
    I tested this with Microsoft Visual Studio 2022, version 17.8.3.

    Because __VA_OPT__ is a C++20 feature you will need to specify std:c++20 or later, but on my system that does not help.
    However if you use /Zc:preprocessor it does have some effect. The following code will work as in most other compilers:

    #define _sdk_log(fmt, ...) \
        printf(fmt, ##__VA_ARGS__)
    #endif
    

    Now your code will compile the same in MSVC, gcc and Clang. The ## will eat any leading comma in most compilers, the above compiler switch brings MSVC in line with everyone else.

    This is documented by MS here: https://learn.microsoft.com/en-us/cpp/preprocessor/preprocessor-experimental-overview?view=msvc-170#comma-elision-in-variadic-macros