Extra tokens at end of #ifdef directive

c, c++

Solution

As far as C++ is concerted, `#ifdef C++11` is a syntax error. There is no rule saying a compiler has to reject a program with a syntax error.

1.4 Implementation compliance [intro.compliance]

The set of diagnosable rules consists of all syntactic and semantic rules in this International Standard except for those rules containing an explicit notation that "no diagnostic is required" or which are described as resulting in "undefined behavior."

[...]

If a program contains a violation of any diagnosable rule or an occurrence of a construct described in this Standard as "conditionally-supported" when the implementation does not support that construct, a conforming implementation shall issue at least one diagnostic message.

A warning is a diagnostic message. The compilers are perfectly within their rights to continue to successfully compile the program, as long as they ensure they show you that one diagnostic message. Since compilers have historically accepted such directives, and accepting such directives does not conflict with the requirements of the standard, they continue to do so.

At least as far as GCC is concerned, you can ask to make all standard-required diagnostics a hard error with the `-pedantic-errors` option.

$ printf "#ifdef C++11\n#endif\n" | gcc -std=c++11 -pedantic-errors -E -x c++ -
# 1 "<stdin>"
# 1 "<command-line>"
# 1 "<stdin>"
<stdin>:1:9: error: extra tokens at end of #ifdef directive

Problem

Why does the following code compiles? ``` #ifdef C++11 // ... #endif int main() {} ``` gcc 4.8.0 gives me the following warning: extra tokens at end of #ifdef directive According to the standard, the macro name can contain only letters, digits and underscore character. Maybe because this? ISO/IEC 14882:2011 16.1 Conditional inclusion [cpp.cond] 6 Each directive’s condition is checked in order. If it evaluates to false (zero), the group that it controls is skipped: directives are processed only through the name that determines the directive in order to keep track of the level of nested conditionals; the rest of the directives’ preprocessing tokens are ignored, as are the other preprocessing tokens in the group. Only the first group whose control condition evaluates to true (nonzero) is processed. If none of the conditions evaluates to true, and there is a #else directive, the group controlled by the #else is processed; lacking a #else directive, all the groups until the #endif are skipped.151 I can't understand this quote correctly.

Original source

Related problems