10

I try to get at the first actual parameter sent to a variadic macro. This is what I tried, and which does not work in VS2010:

#define FIRST_ARG(N, ...) N
#define MY_MACRO(...) decltype(FIRST_ARG(__VA_ARGS__))

When I look at the preprocessor output I see that FIRST_ARG returns the entire argument list sent to MY_MACRO...

On the other hand when I try with:

FIRST_ARG(1,2,3)

it expands to 1 as intended.

This seems to be somehow the inverse of the problem solved by the infamous two level concat macros. I know that "macro parameters are fully expanded before inserted in the macro body" but this does not seem to help me here as I don't understand what this means in the context of ... and __VA_ARGS__

Obviously __VA_ARGS__ binds to N and is only evaluated later. I tried several ways with extra macro levels but it didn't help.

Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
Bengt Gustafsson
  • 517
  • 4
  • 10

1 Answers1

11

This is a bug in the Visual C++ preprocessor. The workaround listed there works. This:

#define FIRST_ARG_(N, ...) N
#define FIRST_ARG(args) FIRST_ARG_ args
#define MY_MACRO(...) decltype(FIRST_ARG((__VA_ARGS__)))

MY_MACRO(x, y, z)

expands to:

decltype(x)
James McNellis
  • 348,265
  • 75
  • 913
  • 977
  • I note that link has a "workaround" which looks potentially helpful. – aschepler Jan 20 '11 at 18:01
  • 4
    @aschepler: Yes; I was just looking at that and testing it with the OP's use case. It works just fine and I've added a demonstration to the answer. The workaround also demonstrates the overarching rule when writing macros: "if at first you don't succeed, add more parentheses." ;-) – James McNellis Jan 20 '11 at 18:04
  • See also [here](https://stackoverflow.com/questions/5134523/msvc-doesnt-expand-va-args-correctly/5134656#5134656) – ghd Feb 14 '17 at 10:08
  • 2
    gee VS... always the better surprise compiler :'( – v.oddou May 16 '19 at 07:26