Defect Report #142

Submission Date: 23 Feb 95
Submittor: BSI
Source: Clive D.W. Feather
Question
Submitted to BSI by Clive D.W. Feather [email protected].
In this Defect Report, identifiers lexically identical to those declared in standard headers refer to the identifiers declared in those standard headers, whether or not the header is explicitly mentioned.
This Defect Report has been prepared with considerable help from Mark Brader, Jutta Degener, Ronald Guilmette, and a person whose employment conditions require anonymity. However, except where stated, opinions expressed or implied should not be assumed to be those of any person other than myself.
Defect Report UK 026: Reservation of macro names
Is it permitted to #undef a reserved macro name? Consider the translation unit:
#include <errno.h>
#undef EASTER
#undef EDOM
#undef __ERRNO_BASE
int error (void) { return errno == ERANGE; }
Considering each of the three #undef directives independently, is each directive permitted in a strictly conforming program? Is the translation unit strictly conforming?
Subclause 7.1.3 describes various classes of reserved identifiers, and then states:
If the program declares or defines an identifier with the same name as an identifier reserved in that context (other than as allowed by 7.1.7), the behavior is undefined.
However, this does mention the use of #undef. Subclause 7.1.7 does so, for certain identifiers, but in rather ambiguous words:
The use of #undef to remove any macro definition will also ensure ...
It has been suggested that this wording merely describes a strictly conforming coding technique, rather than establishing a special case (rather like the wording about placing the name in parentheses does).
Therefore, can a strictly conforming program #undef a name which is reserved for any use at that point?
There is a good reason to allow such an #undef. A program can make use of a identifier which is convenient but would otherwise be reserved (for example, the identifier EASTER). There is also a good reason to forbid it: the macro ERANGE might actually be defined as (__ERRNO_BASE + 42). This leads to the conclusion that it might be best to permit it for some names but not others.
A further example [inserted at the request of BSI] is the translation unit:
#include <stdlib.h>
#undef __INCLUDED_STDLIB_H
#include <stdlib.h>
Suggested Technical Corrigendum:
Add to the end of subclause 7.1.3:
If the program removes (with #undef) the macro definition of an identifier in the first group listed above, the behavior is undefined.
Technical Corrigendum
Replace the third bullet in subclause 7.1.3 with the following:
Each macro name in any of the following subclauses (including Future library directions) is reserved for use as specified if any of its associated headers is included, unless explicitly stated otherwise.
Forward reference: 7.1.7.
Previous Defect Report < - > Next Defect Report