2 ms·
This doesn't seem quite right. Did you maybe mean "#undefine FOO" or "! defined(FOO)"? Whether BAR gets expanded or not, in your example it looks like it wou
by nkurz 11y ago
This doesn't seem quite right. Did you maybe mean "#undefine FOO" or "! defined(FOO)"? Whether BAR gets expanded or not, in your example it looks like it would always evaluate true. Or am I misunderstanding the ambiguity?
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?
- evmar 11y agoI'm not sure -- I'm going off what the Clang bug says. They have a spec ref in there. (Note that you can't trust your intuition on how compilers work, you can only trust the spec and experiments.) If it helps any here is the real-world code where this problem came up: https://codereview.chromium.org/1584203002/ https://codereview.chromium.org/1584203002/ Edit: another reference: https://gcc.gnu.org/onlinedocs/cpp/Defined.html#Defined 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."
- nkurz 11y agoOK, I've now tested. For this test code: #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/ http://gcc.godbolt.org/ And MSVC can be tested online here: http://webcompiler.cloudapp.net/ http://webcompiler.cloudapp.net/
- bla2 11y agoAccording to the link posted by evmar, clang warns on this starting at r258128.