T
Tim Rentsch
Robert Gamble said:First off, *ptr is undefined behavior (even after the type it points to
is completed) because the value of ptr is indeterminate, but let's but
that aside for now.
At the point where ptr is dereferenced, it is a pointer to an
incomplete type. The result is therefore an incomplete type (If the
operand has type "pointer to type", the result has type "type").
The first sentence of 6.3.2.1p1 states:
'An lvalue is an expression with an object type or an incomplete type
other than void; if an lvalue does not designate an object when it is
evaluated, the behavior is undefined.'
The first part of this sentence tells us that the result of *ptr is an
lvalue, the second part tells us that since it does not designate an
object the behavior is undefined allowing gcc to refuse to compile the
program.
Whether a pointer value designates an object doesn't have to do with
the type or lvalue-ness of the expression that produced that value.
If you're willing to overlook the value of 'ptr' being indeterminate,
then it might very well have a value that designates an object. For
example:
int main(void)
{
struct foo;
struct foo *ptr /* = &abc */;
*ptr;
struct foo {
int x;
} abc;
return 0;
}
If the indeterminate value happens to coincide with the
not-allowed-because-of-forward-reference-problems "initialization"
inside the comment, then 'ptr' would designate an object (and
incidentally one of of appropriate type).
The appropriate section to cite here is 6.3.2.1 p2
"... If the lvalue has an incomplete type and does not have
array type, the behavior is undefined."