ylliX - Online Advertising Network
How to build GenAI mock server?

Understanding why certain preprocessor macro overloads don’t work


I’m currently working in VS2022 writing a set of macros using the variadic macro tricks described in Overloading Macro on Number of Arguments. Specifically, I’m trying to do 3 things with scoped types: one is to generate the scoped type itself, one is to create a string literal of the scoped type, and one is trying to create a variable name from the scoped type by replacing :: with _. So far my macros looks like this:

#define GET_ARGS(_1, _2, _3, _4, _5, ARGS, ...) ARGS

// these generate the actual scoped name
#define SCOPE1(_1) _1
#define SCOPE2(_1, ...) _1##::## SCOPE1(__VA_ARGS__)
#define SCOPE3(_1, ...) _1##::## SCOPE2(__VA_ARGS__)
#define SCOPE4(_1, ...) _1##::## SCOPE3(__VA_ARGS__)
#define SCOPE5(_1, ...) _1##::## SCOPE4(__VA_ARGS__)
#define GET_SCOPE(...) GET_ARGS(__VA_ARGS__, SCOPE5, SCOPE4, SCOPE3, SCOPE2, SCOPE1)(__VA_ARGS__)

// these generate a string of the scoped name
#define STR1(_1) #_1
#define STR2(_1, ...) #_1 "::" STR1(__VA_ARGS__)
#define STR3(_1, ...) #_1 "::" STR2(__VA_ARGS__)
#define STR4(_1, ...) #_1 "::" STR3(__VA_ARGS__)
#define STR5(_1, ...) #_1 "::" STR4(__VA_ARGS__)
#define GET_STR(...) GET_ARGS(__VA_ARGS__, STR5, STR4, STR3, STR2, STR1)(__VA_ARGS__)

// these generate a name for a variable
#define VAR1(_1) _1
#define VAR2(_1, ...) _1##_## VAR1(__VA_ARGS__)
#define VAR3(_1, ...) _1##_## VAR2(__VA_ARGS__)
#define VAR4(_1, ...) _1##_## VAR3(__VA_ARGS__)
#define VAR5(_1, ...) _1##_## VAR4(__VA_ARGS__)
#define GET_VAR(...) GET_ARGS(__VA_ARGS__, VAR5, VAR4, VAR3, VAR2, VAR1)(__VA_ARGS__)

To test this, I have this simple test code:

namespace ns1
{
namespace ns2
{
struct cls {};
}
}

GET_SCOPE(int) i;
GET_SCOPE(ns1, ns2, cls) v;

const char* sv = GET_STR(ns1, ns2, cls);

int GET_VAR(ns1, ns2, cls);

The first three cases work great, and produce exactly the results I want:

int i;
ns1::ns2::cls v;

const char* sv = "ns1" "::" "ns2" "::" "cls";

However, the last case fails for reasons I don’t understand. The IDE resolves it as
int ns1_VAR2(ns2, cls); For the record, I do have /Zc:preprocessor enabled to make the preprocessor compliant. Can anyone explain why only the one case fails when the others succeed? I’ve also tried replacing _ with other characters just in case that was the issue, but there was no change.



Source link

Leave a Reply

Your email address will not be published. Required fields are marked *