Defect Report #047

Submission Date: 10 Dec 92
Submittor: WG14
Source: X3J11/92-040 (Randall Meyers)
Question 1
Are the following declarations strictly conforming?
/* 1 */ struct S;
/* 2 */ struct S *f(struct S *p) {return p; }
/* 3 */ struct S *g(struct S a[]) {return a; }
/* 4 */ int *h(int a2[][]) {return *a2; }
/* 5 */ extern struct S es1;
/* 6 */ extern struct S es2[1];
The declaration of struct tag S introduces an incomplete type
(subclause 6.5.2.3, page 62, lines 25-29) that may only be used when
the size of the type is not needed.
The function f therefore is a fairly common and non-controversial
use of an incomplete pointer type by a function. It is strictly conforming.
The function g is more interesting. A parameter of type array
is adjusted to pointer type (subclause 6.7.1, page 82, lines 23-26).
(Note that is an adjustment of the type of the parameter definition.
It is not a conversion, as is what happens when an argument of type
array is passed to a function.) Thus, the type of parameter a
is pointer to struct S. This would seem to make the function
g the same case as function f. However, subclause 6.1.2.5,
page 23, lines 23-24 (also Footnote 17) disallow array types from
having an incomplete element type (like struct S). This raises
the question, is function g strictly conforming because the
type of a is really pointer, or is function g not strictly
conforming because a had an invalid array type before the compiler
in effect rewrote the declaration?
The function h is similar to function g. The type of a2
after adjustment is pointer to array of unknown size of int,
which does not violate any rules. However, before adjustment, the
type of a2 is illegal because it is an array whose element type
is array of unknown size, which is an incomplete type.
In previous Committee discussion that occurred concerning Defect Report
#017 Question 10, the Committee took the position that a declaration
like that of es1 was strictly conforming, since the size of
es1 is not needed for an external reference, and thus was similar
to the cases described in Footnote 63 in subclause 6.5.2.3 on page
62.
The declaration of es2 also does not require its size to be
known. However, it appears that the rule from subclause 6.1.2.5, page
23, lines 23-24 that prohibits an incomplete array element type makes
es2 not strictly conforming.
Response
First of all, no constraints are violated. Therefore, no diagnostics
are required.
Declarations 1, 2, and 5 are strictly conforming. Declarations 3,
4, and 6 are not, and therefore cause undefined behavior.
The struct S is an incomplete type (subclause 6.5.2.3, page
62, lines 25-28). Also, an array of unknown size is an incomplete
type (subclause 6.5.4.2, page 67, lines 9-10). Therefore, arrays of
either of the above are not strictly conforming (subclause 6.1.2.5,
page 23, lines 23-24). This makes declarations 3, 4, and 6 not strictly
conforming. (But an implementation could get it right.)
As an aside, array parameters are adjusted to pointer type (subclause
6.7.1, page 82, lines 23-24). However, there is nothing to suggest
that a not-strictly-conforming array type can magically be transformed
into a strictly conforming pointer parameter via this rule.
The types in question can be interpreted two different ways. (Array
to pointer conversion can happen as soon as possible or as late as
possible.) Hence a program that uses such a form has undefined behavior.
Previous Defect Report
< - >
Next Defect Report