Defect Report #016
Submission Date: 10 Dec 92
Submittor: WG14
Source: X3J11/90-052 (Sam Kendall)
Question 1
I can find no prohibition of the following translation unit:
struct foo x;
struct foo { int i; };
What I was looking for, but didn't find, was a statement
that an implicitly initialized declaration of an object with static
storage duration must have object type. Is this translation unit legal?
Response
The translation unit cited is valid. It falls into the same
category of construct as
int array[];
int array[17];
Objects may be declared without knowing their size. However,
the standard is clear in what cases such an object may or may not be
used, prior to the actual definition of the object.
Question 2
This one is relevant only for hardware on which either null
pointer or floating point zero is not represented as all zero
bits.
Consider this sentence in subclause 6.5.7 (starting on page 71,
line 41):
If an object that has static storage duration is not
initialized explicitly, it is initialized implicitly as if every member
that has arithmetic type were assigned 0 and every member that has
pointer type were assigned a null pointer constant.
This implies that you cannot implicitly initialize a
union object that could contain overlapping members with different
representations for zero/null pointer. For example, given this
translation unit:
union { char *p; int i; } x;
If the null pointer
is represented as, say, 0x80000000, then there is no
way to implicitly initialize this object. Either the p
member contains the null pointer, or the i member
contains 0, but not both. So the behavior of this translation unit is
undefined.
This is a bad state of affairs. I assume it was not the
Committee's intention to prohibit a large class of implicitly
initialized unions; this would render a great deal of existing code
nonconforming.
The right thing - although I can find no support for this idea
in the draft - is to implicitly initialize only the first member of a
union, by analogy with explicit initialization. Here is a proposed new
sentence; perhaps it can be saved for the next time we make a C
standard. (This sentence also tries to get around the difficulty of the
old ``as if ... assigned'' language in dealing with const
items; Dave Prosser tipped me off there.)
- If an object that has static storage duration is not initialized
explicitly, it is initialized implicitly according to these rules:
- if it is a scalar with pointer type, it is initialized implicitly
to a null pointer constant;
- if it is a scalar with non-pointer type, it is initialized
implicitly to zero;
- if it is an aggregate, every member is initialized (recursively)
according to these rules;
- if it is a union, the first member is initialized (recursively)
according to these rules.
Correction
In subclause 6.5.7, page 71, line 41 through page 72, line 2,
change:
If an object that has static storage duration is not initialized
explicitly, it is initialized implicitly as if every member that has
arithmetic type were assigned 0 and every member that has pointer type
were assigned a null pointer constant.
to:
- If an object that has static storage duration is not initialized
explicitly, then:
- if it has pointer type, it is initialized to a null pointer;
- if it has arithmetic type, it is initialized to zero;
- if it is an aggregate, every member is initialized (recursively)
according to these rules;
- if it is a union, the first named member is initialized
(recursively) according to these rules.
Previous Defect Report
< - > Next Defect Report