clanguage-lawyercollisionidentifierreserved

Does non-reserved identifier at translation phase 4 make it impossible to reserve a file scope identifier at translation phase 7?


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?


Solution

  • 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".