Defect Report #044
Submission Date: 10 Dec 92
Submittor: WG14
Source: X3J11/92-010 (Steve M. Hoxey)
Question 1
Subclause 7.1.6, page 98, lines 24-30 describe the macro
offsetof(type, member_designator)
``which expands to an integral constant expression that has type
size_t, ...''
How is this statement to be interpreted? The expansion of the macro
offsetof is
- an expression which can be evaluated during translation, the
value of which is in the range representable by a size_t type.
Or
- an expression as (a) above, but further constrained to be an
``integral constant expression'' as defined in subclause 6.4,
page 55, lines 17-21.
Response
Neither alternative (a) nor (b) in Question 1 fully captures the intent.
What is intended is exactly what is specified in the C Standard. A
strictly conforming program shall not produce output that varies depending
upon details of implementation of facilities defined by the standard
headers. Hence, use of the offsetof macro, in a context requiring
an integer constant expression, per se does not render a program not
strictly conforming.
Further clarification provided by David Prosser:
Although the replacement for the offsetof macro must be an integral
constant expression, and must follow all the constraints appropriate
to expressions, an implementation is permitted to make use of its
extensions to constant expressions that behave like integral constant
expressions. This is why the sample replacement expressions for the
offsetof macro in the Rationale are valid candidates (for many
implementations) but do not come under the strict definition of integral
constant expression that strictly conforming code must follow. In
particular, this is why the offsetof macro exists: there was
otherwise no portable means to compute such translation-time constants.
Therefore, of the two choices, (b) is the closest, but it is not the
whole story.
Question 2
Subclause 5.1.1.1, page 5, lines 11-20 define a ``translation unit''
to be equivalent to the sequence of preprocessing tokens and white-space
characters which exists at the end of translation phase 4 (subclause
5.1.1.2). Later in translation phases 5, 6, 7, these preprocessing
tokens are converted to tokens and syntactically and semantically
analyzed and translated.
Therefore, must a conforming implementation provide strictly conforming
expansions of macros defined by the standard headers, such that any
use of the resulting preprocessing token sequence, and ultimately
the token sequence, beyond phase 4 does not alter the behavior of
an otherwise strictly conforming program? See also clause 4 Compliance,
page 4, lines 24-26.
Response
A conforming implementation need not provide strictly conforming expansion
of macros defined by the standard headers.
Question 3
Assuming (b) is the correct interpretation of Question 1, if a particular
implementation expands offsetof into an expression which contains
operands and/or operators which result in a violation of the definition
of ``integral constant expression'' from subclause 6.4, page
55, lines 17-21, does this situation constitute:
- a constraint violation since the expansion presented for further
translation is not an ``integer constant expression?''
or
- undefined behavior since the definition of ``integral constant
expression'' appears in a ``shall'' requirement in the semantic
description of subclause 6.4 Constant expressions?
Response
The response to Question 1 makes this a moot question.
Question 4
Assuming (b) is the correct interpretation of Question 3, if within
a translation unit at a point where an ``integer constant expression''
is required to satisfy a language constraint - such as to specify
the size of a bit-field member of a structure, the value of an enumeration
constant, the size of an array, or the value of a case constant -
does the use of the macro offsetof constitute:
- a constraint violation?
or
- the use of undefined behavior, which renders the translation
unit to be not strictly conforming?
Response
The response to Question 1 makes this a moot question.
Question 5
Revisiting (b) as the correct interpretation of Question 1, it seems
the only possibility for a definition of the macro offsetof
constitutes use of an identifier from the reserved name space to define
a builtin which interrogates the translator's symbol table in a fashion
analogous to the sizeof operator. Further, this builtin must
appear syntactically as a keyword rather than an identifier to avoid
the constraint violation of subclause 6.4, page 55, line 9, which
invalidates the use of what appears to be a function call within that
which is otherwise required to be a constant expression.
Further, implementing an expansion for offsetof as described
in the previous paragraph would violate the implementation constraint
outlined in Question 2 above, since the expansion would inject preprocessing
tokens requiring recognition of a keyword outside the scope of a strictly
conforming program.
In any case, the implication is that the fragment:
#include <stddef.h>
static struct x {int field1, field2; } s;
enum fields {F0, F1, F2 = offsetof(struct x,field2), F3 };
is either rendered not strictly conforming or the implementation is
rendered a nonconforming implementation.
Alternatively, if the answer to Question 2 above is no, then the following
questions are raised:
Since translation phases 1 through 4 may introduce into the translation
unit token sequences which are not strictly conforming, what mechanism
exists, if any, to determine whether such sequences originated from
the program source?
How is one to interpret the meaning of ``strictly conforming program''
from clause 4, page 3, lines 38-40, given that subclause 5.1.1.1,
page 5, lines 12-15 define the translation unit to be ``a source
file together with all the headers and source files included via the
preprocessing directive #include, less any source lines skipped
by any of the conditional inclusion preprocessing directives?''
It seems that any program which makes use of the macro offsetof
in the context of a constraint requirement mandating an ``integer
constant expression'' will require use of unspecified, undefined,
or implementation-defined behavior.
As near as I can tell, offsetof is the only macro defined by
the C Standard which can alter the behavior of a strictly conforming
program as a consequence of its own definition.
Response
The response to Question 1 addresses this issue.
Previous Defect Report
< - >
Next Defect Report