0

currently I'm trying to compile some code with Visual Studio 2015 Service Pack 2 that makes use of the following macros not written by me:

#define REM(...) __VA_ARGS__
#define EAT(...)

// Retrieve the type
#define TYPEOF(x) DETAIL_TYPEOF(DETAIL_TYPEOF_PROBE x,)
#define DETAIL_TYPEOF(...) DETAIL_TYPEOF_HEAD(__VA_ARGS__)
#define DETAIL_TYPEOF_HEAD( x , ... ) REM x
#define DETAIL_TYPEOF_PROBE(...) (__VA_ARGS__),
// Strip off the type
#define STRIP(x) EAT x
// Show the type without parenthesis
#define PAIR(x) REM x

Supposedly the TYPEOF macro would isolate the type of an expression. I have tried to invoke the TYPEOF macro with the following call:

TYPEOF( (int) m ) c;

In theory, the result should be

int c;

but instead the preprocessor outputs

int, m, c;

Replacing

#define DETAIL_TYPEOF_HEAD(x, ...) REM x

with

#define DETAIL_TYPEOF_HEAD( x , ... ) X = x and VA_ARGS = __VA_ARGS__

Yields this output:

X = (int), m, and VA_ARGS = c;

It seems that receiving the input (int), m, the DETAIL_TYPEOF_HEAD macro is unable to pick the first entry x from the variadic parameter list and instead puts the whole list into x.

Do you know this phenomenon?

Regards

user5024425
  • 397
  • 3
  • 14
  • 2
    I think I've encountered this phenomenon before. It's called *the Microsoft compiler*. – n. m. could be an AI Oct 13 '16 at 19:26
  • 1
    @n.m. I'd normally flag that as not constructive, but in this case you're probably right. http://stackoverflow.com/questions/9183993/msvc-variadic-macro-expansion – lcs Oct 13 '16 at 19:47
  • @lcs well I love to leave a little joke comment here and there, but on;y after I check it against all available major compilers and the text of the standard. – n. m. could be an AI Oct 13 '16 at 21:13
  • I think fixing this even with the example is beyond my capabilities. Do you have an idea? – user5024425 Oct 14 '16 at 06:53

1 Answers1

0

Ok, I have no idea how exactly but this seems to give the expected result:

// Retrieve the type
#define DETAIL_TYPEOF_HEAD_(x , ...) REM x
#define DETAIL_TYPEOF_HEAD( args ) DETAIL_TYPEOF_HEAD_ args
#define DETAIL_TYPEOF_PROBE(...) (__VA_ARGS__),
#define DETAIL_TYPEOF(...) DETAIL_TYPEOF_HEAD((__VA_ARGS__))
#define TYPEOF(x) DETAIL_TYPEOF(DETAIL_TYPEOF_PROBE x,)

Adding parentheses seemed to help a lot.

user5024425
  • 397
  • 3
  • 14