Defect Report #043
Submission Date: 10 Dec 92
Source: X3J11/92-004 (Robert Paul Corbett)
Subclause 7.1.6 defines NULL to be a macro ``which expands
to an implementation-defined null pointer constant.'' Subclause
18.104.22.168 defines a null pointer constant to be ``an integral constant
expression with the value 0, or such an expression cast to type void
*.'' The expression 4-4 is an integral constant expression
with the value 0. Therefore, Standard C appears to permit
#define NULL 4 - 4
as one of the ways NULL can be defined in the standard headers.
By allowing such a definition, Standard C forces programmers to parenthesize
NULL in several contexts if they wish to ensure portability.
For example, when NULL is cast to a pointer type, NULL
must be parenthesized in the cast expression.
At least one book about Standard C suggests defining NULL as
#define NULL (void *) 0
That definition leads to a subtler version of the problem described
above. Consider the expression NULL[p], where p is an
array of pointers. The expression expands to (void *)0[p] which
is equivalent to (void *)(p). I doubt many users would expect
such a result.
Have I correctly understood Standard C's requirements regarding NULL?
If not, what are those requirements?
Add to subclause 7.1.2, page 96 (before Forward references):
Any definition of an object-like macro described in this clause shall
expand to code that is fully protected by parentheses where necessary,
so that it groups in an arbitrary expression as if it were a single
Subclause 7.1.3 implies that an identifier that begins with an underscore
cannot be defined as a macro name in any source file that includes
at least one standard header. Footnote 91 emphasizes this restriction.
Nonetheless, there are texts on Standard C that imply that such macro
definitions are allowed.
The first paragraph of subclause 7.1.3 states that each header optionally
declares or defines identifiers which are always reserved either for
any use or for use as file scope identifiers. The second bullet item
states, ``All identifiers that begin with an underscore are always
reserved for use as identifiers with file scope in both the ordinary
identifier and tag name spaces.'' The final sentence 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.'' Taken together, these statements imply
that an identifier that starts with an underscore cannot be defined
as a macro in a source file that includes at least one of the standard
Can an identifier that starts with an underscore be defined as a macro
in a source file that includes at least one standard header?
No. See subclause 7.1.3 and Footnote 91.
Previous Defect Report
< - >
Next Defect Report