ISO/IEC JTC1/SC22/WG14 N720
Issues related to DRs 060 to 178
Clive D.W. Feather
I've been looking through the defect log; specifically DRs from 060
onwards (most of which are mine :-). Apart from those you've handed out
because they said "future change", there are quite a lot that either point
out minor changes that would improve things, or that say things like "this
should be addressed at the next revision". I have put together a set of
notes and suggested changes for these.
Minor substantive changes
There are various places where a DR has indicated somewhere where the
meaning of the Standard could be improved by making a normative change
which could plausible affect some implementations. I still hope they are
In 22.214.171.124 paragraph 3, insert after "of zero length":
Apart from grouping and mon_grouping, the strings shall start and
end in the initial shift state.
In 126.96.36.199, paragraph 5, after:
... the types of the arguments after promotion are not compatible
with those of the parameters after promotion, the behaviour is
with one exception: if the two types are required to have the same
representation for some or all values, the behaviour is undefined
only if the value of the argument is not such a value. [*]
[*] Thus a nonnegative signed integer may be passed to a parameter
that has the corresponding unsigned type, and a pointer to void
may be passed to a parameter with pointer to a character type.
In 188.8.131.52 paragraph 5, change "one exception" to "two exceptions", and
Secondly, if the two members have types which are required to have
the same representation for some or all values, the value stored may
be accessed using any member with a type for which that value must
have the same representation.
In 184.108.40.206, change the first constraint to:
The operand of the unary & operator shall be a function designator,
the result of a  or unary * operator, or an lvalue that designates
an object ...
Add to the end of paragraph 3:
If the operand is the result of a  or unary * operator, neither
that operator nor the & operator are evaluated, and the result shall
be as if both were omitted, even if the intermediate object does not
Change the first sentence of footnote 54 to:
Thus &*E is equivalent to E (even if E is a null pointer), and
&(E1[E2]) to (E1+E2).
In 220.127.116.11 add a constraint:
The parameters in a parameter-type-list that is part of a function
definition shall not have incomplete type.
and a Semantics paragraph:
If the function declarator is not part of a function definition, the
parameters may have incomplete type.
DRs 096 and 110
In 18.104.22.168 add a constraint:
The element type shall not be an incomplete or function type.
Change the first constraint to:
A declaration shall declare at least a declarator (excluding the
parameters of a function or the members of a structure or union), a
tag, or the members of an enumeration.
In 22.214.171.124, append to paragraph 2:
If the argument is not zero, EDOM, ERANGE, or any value that a
library function might store in errno, the behaviour is undefined.
In 126.96.36.199 paragraph 2, change "any other operation" to:
... any other operation (except an unsuccessful call to setvbuf) ...
Add a constraint to 6.3.1:
Except for function calls as described in 188.8.131.52, there shall be a
declaration of any identifier visible at the point it is used as a
Adopt the replacement wording for 184.108.40.206 given in the DR.
In 6.8.4 paragraph 2, change:
... to the current token.
... up to an unspecified character within the current token.
Adopt the replacement wording for 220.127.116.11 and 6.3.15 given in the DR.
Adopt the replacement wording for 6.8.5 given in the DR.
[This wording makes a retained #error violate a constraint.]
Consistency and clarification changes
These changes are intended to ensure that related parts of the Standard
are consistent with one another, or to make the text clearer and harder
to misread. All should be uncontroversial.
In 18.104.22.168 paragraph 12, delete:
"as necessary to achieve the appropriate alignment"
"or for any other purpose"
Similarly in paragraph 14.
Add to 22.214.171.124:
The address of an object is constant so long as its storage is
guaranteed to be reserved. Two objects which are both guaranteed to
have storage reserved at the same point in the execution of the
program have different addresses. Any two functions have different
Append to 7.1.2:
Any declaration of a library function shall have external linkage.
In 7.1.7, modify the words:
... additionaly implemented as a macro defined in the header ...
by inserting "function-like" before "macro".
In 6.3.8 paragraph 5, change:
... the result is undefined: ...
... the behaviour is undefined: ...
In 126.96.36.199, add to paragraph 3:
If the array object has register storage class, the behaviour is
Add to 3.18:
The implementation must correctly translate a given program unless
it can determine that every possible execution of that program would
result in undefined behaviour.
Add the list of items in the DR to subclause I.2.
In 188.8.131.52 and 184.108.40.206, change footnote 173 to:
The results of all floating conversions of a negative zero, and of
negative values that round to zero, include a minus sign.
In 7.1.7, change:
... so a library function should not be declared explicitly if its
header is included.
... so if a library function is declared explicitly when its header
is included, one of the techniques shown below should be used to
ensure the declaration is not affected by such a macro.
In 220.127.116.11 and 18.104.22.168, '#' flag, change:
... the first digit of the result to be a zero.
... the first digit of the result to be a zero (if the value and
precision are both 0, a single 0 is printed).
In 6.5.6, add a new example 4, renumbering the existing one:
4. Typedefs can be used even where the type name is given a special
typedef void NO_ARGUMENTS;
typedef int integer;
integer main (NO_ARGUMENTS)
/* ... */
is a valid definition of the function main in 22.214.171.124.1.
In 7.1.3, paragraph 1, bullet points 2 and 5, change:
... reserved for use as identifiers ...
... reserved for use as macros and as identifiers ...
In 7.19, change each instance of:
(followed by any combination of digits, letters, and underscore)
(possibly followed by ...)
In 126.96.36.199 and 188.8.131.52, 'n' specifier, change the last sentence to:
No argument is converted, but one is consumed. If the conversion
specification with this conversion specifier is not one of %n, %ln,
%lln, or %hn, the behaviour is undefined.
In 184.108.40.206, 'n' specifier, add %lln to the list.
In I.2, add:
A %n conversion specification for the fprintf or fscanf functions is
not one of %n, %ln, %lln, or %hn. (220.127.116.11, 18.104.22.168, 22.214.171.124,
In I.2 referring to 6.3, add "a type compatible with" in the places that
TC1 changed 6.3 itself.
The following difficult issues are still open and need considering.
What is the required precision of floating point calculations ?
DRs 072, 073 and 178
These DRs leave the issue of the "struct hack" totally confused.
One way out may be to explicitly bless the following:
/* other members */
T last ; /* Last member may be an indeterminate size array */
sizeof (struct hack) would equal offsetof (struct hack, last). The
notation is an explicit warning that last will be accessed as a VLA
within malloced memory.
The issue of sequence points, parallel evaluation, and so on still needs
to be faced squarely. It isn't easy [example: x = f (x++)].
The Technical Corrigendum given in the DR has not been made, which is lucky,
because it misses the point. The words "unless explicitly stated otherwise"
aren't needed, because they are implicit in any reading of the Standard.
What the DR asked about is using #undef with reserved identifiers,
something which is currently strictly conforming. The following change
(suggested in the DR) is necessary to allow an implementation to make use
of flag macros such as _INCLUDED_STDIO_H.
Append to 7.1.3:
If the program removes (with #undef) any macro definition of an
identifier in the first group listed above, the behaviour is
Many constraints refer to lvalues, yet the current definition can make
it impossible to tell if something is an lvalue until runtime. [126.96.36.199,
188.8.131.52, 6.3.16 are mentioned; 184.108.40.206 is addressed by DR 076 above.]
There are a number of defects in the rules for pointer comparison. These
should be fixed.