http://reviews.llvm.org/D15866
#define FOO
#define BAR defined(FOO)
#if BAR
...
#else
...
#endif
clang and gcc will pick the #if branch while Visual Studio will take the #else branch.http://reviews.llvm.org/D15866
#define FOO
#define BAR defined(FOO)
#if BAR
...
#else
...
#endif
clang and gcc will pick the #if branch while Visual Studio will take the #else branch.I am also reminded of the button I used to have that said, "Defining define is undefined."
#define a(x,y) x+y
void f(int i)
{
a(i,+);
}
will compile without errors with cl but not with any other compiler.It might be telling that I also don't understand the Clang bug report as written. I think there are typos in the examples. Is the switch from "HAVE_FOO_BAR" to "HAVE_FOO" in the first example intentional? Is the construct "#defined" (with a final 'd') intentional in the second?
If it helps any here is the real-world code where this problem came up:
https://codereview.chromium.org/1584203002/
Edit: another reference: https://gcc.gnu.org/onlinedocs/cpp/Defined.html#Defined "If the defined operator appears as a result of a macro expansion, the C standard says the behavior is undefined."
#define FOO
#define BAR defined(FOO)
#if BAR
#error "true"
#else
#error "false"
#endif
Clang, GCC, and ICC evaluate the "true" branch, while MSVC evaluates the "false" branch.For the same test code with first line changed to "undef":
#undef FOO
#define BAR defined(FOO)
#if BAR
#error "true"
#else
#error "false"
#endif
MSVC, Clang, GCC, and ICC all agree on "false".Importantly, though, when used with "/Wall", MSVC gives this error message in both cases:
main.cpp(3): warning C4668: 'definedFOO' is not defined as
a preprocessor macro, replacing with '0' for '#if/#elif'
None of the other three compilers give any warnings even with '-Wall -Wextra -pedantic". So there definitely is a difference in behavior, but I don't think it's actually the one that's presumed in that bug.For further experimentation, Clang, GCC, and ICC can be tested online here: http://gcc.godbolt.org/
And MSVC can be tested online here: http://webcompiler.cloudapp.net/
https://gcc.gnu.org/onlinedocs/cpp/Computed-Includes.html
#define SYSTEM_H "system_1.h"
...
#include SYSTEM_H