Re: struct type completion



On Mon, 18 Apr 2005 19:03:54 +0000, S.Tobias wrote:

> Lawrence Kirby <lknews@xxxxxxxxxxxxxxx> wrote:
>> On Mon, 18 Apr 2005 15:12:46 +0000, S.Tobias wrote:
>
> Thank you very much for answering. However I disagree with you.
>
>> > I'm trying to understand how structure type completion works.
>> >
>> > # A structure or union type of unknown
>> > # content (as described in 6.7.2.3) is an incomplete type. It
>> > # is completed, for all declarations of that type, by
>> > ^^^
>> > # declaring the same structure or union tag with its defining
>> > # content later in the same scope.
>> > ^^^^^
>> > (6.2.5#23)
>> >
>> > # [#3] All declarations of structure, union, or enumerated
>> > ^^^
>> > # types that have the same scope and use the same tag declare
>> > ^^^^^^^^^^^^
>> > # the same type. The type is incomplete100) until the
>> > ^^^^^^^^^^^^^^
>> > # closing brace of the list defining the content, and complete
>> > # thereafter.
>> > (6.7.2.3#3)
>> > (both excerpts are from n869.txt, but they're the same in the Std)
>> >
>> > So (eg. in a file scope):
>> >
>> > /* 1 */ struct mystruct object;
>> > /* 2 */ struct mystruct { /*...*/ };
>> >
>> > line 1 defines `object' (although at this point the body of `struct
>> > mystruct' is not yet known(?)); and line 1 does not work without
>> > line 2.
>
>> Line 1 is invalid.
>
> I have tried this code with como and gcc, and both exhibit exactly
> same behaviour - try it for yourself: compile as is (ok), delete
> line 2 (error), insert line "test" after line 1 (error), move it
> after line 2 (ok).

Yes, my error. Tentative definitions are allowed to have incomplete type
as long as they don't have internal linkage, I overlooked the last part.

>>When you define an object the type must be complete at
>> the point of definition, it cannot be completed later.
>
> Yes, I think so too.
>
>>Note that you can
>> define a pointer to an incomplete type whch is completed later. All
>> pointer types are object types, even pointers to incomplete or function
>> types.
>
> I'm quite aware of that. You don't even have to complete the type
> (unless you dereference the ptr) - the pointer is still valid. But this
> is not what I want to talk about, and I really do mean an object where
> I put the identifier `object'.
>
> The code is a corner case I wanted to check after reading the above
> quotes from the Standard. I think that they say that struct types
> can be completed later. Please pay attention to the words I underlined;
> I hope you can either agree to my interpretation, or understand
> the reason to my misunderstanding and correct me.

I guess it comes down to what it means by "the same type".

> Reminder: identifiers have the same scope, when their scopes end
> at the same point. Above, the scopes of the declarations are different
> (they start at different places), but both declarations have the same
> scope (cf. 6.2.1 p. 6 and 7).

Yes, they have the same scope, and of course the same tag.

>> > What I don't understand is, that the excerpts above seem to dictate that
>> > line 2 fully defines the type for all instances of `struct mystruct'.
>> > The type in line 1 must be a complete type; if it were not, then it
>> > would not be the same type as in line 2, which seems to be required by
>> > the second quote; and - what's obvious - we could not define `object'
>> > (we can't define an object with incomplete type, can we?).
>
>> At the point that line 1 is translated its type is incomplete. For any
>> code after line 2 it would appear complete (except of course that it is
>> invalid).
>
> I thought so too. But this seems to contradict eg. the second quote
> (both in fact): both declarations use the same tag, therefore they
> declare the *same* type; a type cannot be both complete and incomplete.

Not at a particular point in the code, but it can at different points in
the code. It is much the same issue as with function prototypes. If you
have

void foo();

foo(x);

void foo(void);

foo(x);

then the rules that apply to the first foo(x); are different to the
second: the second sees the composite type that includes the prototype.

> [snipped example for pointers - agree, but a different matter]
>
> I assume the type is complete (first quote), that is, both declarations
> declare complete type (whatever incredible that sounds). However
> the last sentence of the second quote seems to contradict it:
>
>> > But then further description seems to contradict this: "... incomplete
>> > until the closing brace ...". If the type in line 1 is complete, then
>> > it needn't be completed, and can't of course be incomplete at the same
>> > time.
>
> (As I read it now, I think it may be understood that closing brace
> completes the type, even for earlier declarations; hence there would
> be no disagreement. But still, the wording is very contrived -
> it would be simpler to say the definition of the (complete) struct
> type may be found later in the translation unit.)

It is a clear indication that the completeness of a type can change
depending on from what point in the source code you view it.

>> A type can be incomplete at one point in the source file and then complete
>> later on.
>
> Hmmm.... I don't have an answer to that, but I strongly disagree.


> If one is incomplete, the other complete, then they're different types,
> I thought that was pretty logical. Could you give some example, or
> a reference (c&v), please?

The wording of the standard you quote above depends on this. A type can
be incomplete at one point in the source code and complete later on. "The
same type" here is simply the opposite of "distinct types".

Consider

{
struct foo { int x } a;
}

{
struct foo { int x } b;
}

a and b have 2 distinct types here, and they are incompatible. Given your
example

>> > /* 1 */ struct mystruct object;
>> > /* 2 */ struct mystruct { /*...*/ };

the fact that the 2 lines refer to the same type means that the completing
of the type in the second line affects the type of object because they are
the same type. So after line 2 (sizeof object) is valid, which it wouldn't
be if they weren't the same type. I think that is all it is saying.

The wording of the standard may not be perfect in this case but I don't
see room for ambiguity. Maybe you could consider that completing the type
doesn't change the type as such, but just changes what you are allowed to
do with it from that point in the code.

Lawrence


.



Relevant Pages

  • Re: struct type completion
    ... >> # content later in the same scope. ... > define a pointer to an incomplete type whch is completed later. ... the scopes of the declarations are different ...
    (comp.lang.c)
  • Re: completion of L^2
    ... David Macmanus wrote: ... > In the book 'Lectures on Groups and Spaces For Physicists', Isham says ... Isn't it the case that completing ... L^2 is incomplete? ...
    (sci.math)
  • completion of L^2
    ... In the book 'Lectures on Groups and Spaces For Physicists', Isham says ... that the space L^2 is incomplete but that it can be completed by filling ... Isn't it the case that completing ...
    (sci.math)