Reputation: 6286
ISO/IEC 9899:202x (E) working draft — February 5, 2020 C17..C2x N2479:
After all replacements due to macro expansion and the defined 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.
In other words:
An identifier that is not defined as a macro is converted to 0 before the expression is evaluated.
This leads to the fact that UNDEFINED == 0
is true:
#if UNDEFINED == 0
#pragma message "UNDEFINED == 0 is true"
#endif
$ gcc t0.c -E
t0.c:3:9: note: '#pragma message: UNDEFINED == 0 is true'
However, how conceptually (logically, mathematically, philosophically, etc.) UNDEFINED
can equal to 0
(leading to UNDEFINED == 0
is true
)?
For example, in IEEE 754
the NaN can be seen as UNDEFINED
(Not a Number, hence, there is no number, the number is not defined, i.e. undefined) and NaN == 0
is false
:
#include <stdio.h>
#include <math.h>
int main( void )
{
printf("NaN == 0 is %d\n", NAN == 0);
return 0;
}
$ gcc t0.c && ./a.exe
NaN == 0 is 0
Question: What is the motivation behind treating in C preprocessor undefined macro as 0?
Upvotes: 4
Views: 1234
Reputation: 6286
Correcting / answering to myself.
NaN
(Not a Number) != undefined FP variable.
I.e. the FP variable (object) is defined, but its content is NaN
.
If you try to compile a C program which uses NAN
w/o including in advance math.h
you'll get compile error (example is given for gcc
): error: 'NAN' undeclared
.
Hence, NaN
cannot be seen as UNDEFINED
.
User @dxiv correctly said:
this behavior (treating undefined macro as 0) does in fact simplify certain constructs
If you'd, for example, argue:
undefined macro shall lead to syntax error -- the preprocessor logic shall be changed
then I'd argue that in real already written code in case of undefined macro the frequency of syntax errors caused by missing #ifdef
in front of #if
will be much higher than the frequency of using #ifdef
(with or w/o the following #if
).
Hence, very possibly it was the reason that WG14 has decided to in case of undefined macro trade usability (i.e. allow use of #if
w/o the leading #ifdef
) over mathematical correctness (i.e. undefined macro shall lead to syntax error).
Upvotes: 1
Reputation: 17648
Question: What is the motivation behind treating in C preprocessor undefined macro as 0?
Emphasis on preprocessor. Undefined macros are treated as 0
by the preprocessor, but not by the compiler. For example, the following fails to compile:
#undef UNDEFINED
#if UNDEFINED == 0 // ok, preprocessor evaluates this as '0 == 0'
int n = UNDEFINED; // error, compiler sees this as 'int n = <undeclared-identifier>;'
#endif
As with other idiosyncrasies, the real answer to the "why" question is "because the C language standard says so". While it is hard to track down the original motivations from decades ago, this behavior does in fact simplify certain constructs, for example the following is enough to check for C99 compliance, without having to worry whether the standard macro __STDC_VERSION__
is defined by the implementation or not:
#if __STDC_VERSION__ >= 199901L
// safely assume C99 or later
#else
// either __STDC_VERSION__ is not defined
// or it is earlier than C99
#endif
Upvotes: 10