Macro replacement interpretation

Section 16.3 paragraph 4 of the C++11 standard reads:

"If the identifier-list in the macro definition does not end with an ellipsis, the number of arguments (including those arguments consisting of no preprocessing tokens) in an invocation of a function-like macro shall equal the number of parameters in the macro definition. Otherwise, there shall be more arguments in the invocation than there are parameters in the macro definition (excluding the ...). There shall exist a ) preprocessing token that terminates the invocation."

Does this mean that invoking a macro with more arguments than there are parameters in the identifier-list in the macro definition is not a preprocessing error ?

Does this mean that invoking a macro with less arguments than there are parameters in the identifier-list in the macro definition is a preprocessing error ?

My testing with the major C++ compilers on Windows and Linux, including gcc, clang, Intel, and Oracle but leaving out VC++ completely because its preprocessor is so C++ standard non-conformant, shows that error messages are usually produced if the number of arguments does not equal the number of parameters in the identifier-list, but this is not always the case ( most notably with Oracle depending on the version ). This suggest that the answer to my first question is NO and the answer to my second question is YES. But I want to know the official answer on whether either situation should be considered a compiler error or whether just a warning is justified.
> Does this mean that invoking a macro with more arguments than there are
> parameters in the identifier-list in the macro definition is not a preprocessing error ?

Yes. There is no error if the macro definition ends with an ellipsis.

1
2
3
4
5
6
7
8
9
10
#include <cstdio>

#define print( a, b, ... ) ( std::printf( #a, (b) ) , std::printf( __VA_ARGS__ ) , std::puts("") )

int main()
{
    print( %d, 100, "%s %d and %c", ", ", 200, 'A' ) ; // 100,  200 and A
    print( %s, "hello", " %s! %s %s!", "world", "hello", "again" ) ; // hello world! hello again!
    print( %d, 1, " %d %d %d %d %d %d", 2, 3, 4, 5, 6, 7 ) ; // 1 2 3 4 5 6 7
}

LLVM and GNU: http://coliru.stacked-crooked.com/a/c1554e62b1889586
Microsoft: http://rextester.com/RNUHP50567
Topic archived. No new replies allowed.