Consider this code:
/*
* stdio.h
*
* note: it is an example of a particular implementation of stdio.h
* containing _x; it is not "my code added to stdio.h"
*/
void _x(void);
/* t627.c */
#define _x 0
#include <stdio.h>
Invocation:
$ gcc t627.c
t627.c:1:12: error: expected identifier or ‘(’ before numeric constant
1 | #define _x 0
| ^
stdio.h:1:6: note: in expansion of macro ‘_x’
1 | void _x(void);
At translation phase 4 the identifier _x
is non-reserved. At translation phase 7 the identifier _x
is reserved (for use as identifier with file scope in both the ordinary and tag name spaces). Since translation phase 4 precedes translation phase 7, then at translation phase 7 the identifier _x
(currently defined as a macro name) is already replaced by its replacement list 0
, invalidating the program.
Does it mean that in cases when the user-defined macro (that begins with an underscore, followed by a lowercase letter) can collide/overlap with the file scope identifier with the same name, such file scope identifier cannot be reserved?
Found a relevant quote from P.J. Plauger (emphasis added):
Remember that the user can write macros that begin with an underscore, followed by a lowercase letter. These names overlap those reserved to the implementor for naming external functions and data objects.
So, the answer seems to be "yes".