In the very simple C program below, what is the expected compiler error? gcc is giving me 1 whereas MSVC 2013 is giving me 2.
#define foo
#define bar (defined(foo))
#if bar
#error 1
#else
#error 2
#endif
My questions are hopefully equally simple:
.
#ifdef foo
#define bar 1
#else
#define bar 2
#endif
The C spec says:
§6.10.1/1 The expression ... may contain unary operator expressions of the form
defined identifier
ordefined(identifier)
which evaluate to1
if the identifier is currently defined as a macro name (that is, if it is predefined or if it has been the subject of a#define
preprocessing directive without an intervening#undef
directive with the same subject identifier),0
if it is not.§6.10.1/4 macro invocations in the list of preprocessing tokens that will become the controlling constant expression are replaced (except for those macro names modified by the
defined
unary operator), just as in normal text. If the tokendefined
is generated as a result of this replacement process or use of thedefined
unary operator does not match one of the two specified forms prior to macro replacement, the behavior is undefined. After all replacements due to macro expansion and thedefined
unary operator have been performed, all remaining identifiers (including those lexically identical to keywords) are replaced with the pp-number 0, and then each preprocessing token is converted into a token.
(emphasis mine)
However, how macro replacement is very complex, and I think MSVC is defining foo
as defined(bar)
which is undefined behavior, wheras GCC is defining foo
as 1
correctly. Since MSVC is then in undefined behavior, it does strange things.
As you say, the easiest fix is
#ifdef foo
#define bar 1
#else
#define bar 2
#endif