Afficher un message
Vieux 31/10/2007, 03h44   #30
Eric Sosman
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: What's the use of anonymous structs?

Francine.Neary@googlemail.com wrote:
> On 30 Oct 2007 at 22:32, Eric Sosman wrote:
>> Francine.Neary@googlemail.com wrote On 10/30/07 18:12,:
>>> Does that mean that the compiler is obliged to use the same memory
>>> layout (i.e. same amount of padding in the same places) for two
>>> structs with identical fields declared in different translation units?
>>> What about if one of the fields has a different name (but the same
>>> type) in the two structs?

>> If the struct tags are different, the types are different.
>> You can test this for yourself:
>>
>> struct A { int i; } a = { 42 };
>> struct B { int i; } b;
>> b = a; /* diagnostic required */
>>
>> Since the two structs are of different types, they could
>> in theory have different representations: The Standard requires
>> common representations for only a few sets of types, and these
>> are not among them. In practice, though, the compiler will
>> process the `struct A' and `struct B' declarations with the
>> same algorithm and get the same result (in the absence of
>> things like `#pragma pack' and similar bletcherous botches).

>
> I guess I was asking specifically about un-named structs in different
> translation units. Consider the following code:
>
>
> /* TU1.c */
>
> void foo(struct { int a; })


Needs an identifier after the } -- let's call it tu1.

> {
> ...
> }
>
>
> /* TU2.c */
>
> void foo(struct { int a; });
> void bar()
> {
> struct { int a; } X;
> X.a=0;
> foo(X);


Diagnostic required. The declared type of the parameter
to foo() is different from that of X, and no conversion is
possible. You've got two untagged struct types in the same
translation unit; the compatibility rule for untagged structs
specifically requires separate translation units.

Within one translation unit, each struct declaration
introduces a new type, distinct from all other types. For
structs with tags the scope rules apply: Two identically-
tagged structs in disjoint scopes are different types, while
two identically-tagged structs in overlapping scopes provoke
a diagnostic. For untagged structs, the behavior is as if
the compiler gave the first one an artificial tag like `#1',
the next one `#2', and so on: Each untagged struct is a distinct
type, no matter what the scope, and two such struct types can
never be compatible.

Some compilers will emit a ful warning about the
declaration of foo(), pointing out that the struct type has
"prototype scope." That is, the type goes out of scope at
the end of the prototype, meaning that any similar struct you
might declare elsewhere will be in a different scope and will
not be of the same type. Thus, there is no way to write a
correct call to foo() in the same translation unit because
there is no way to declare an argument of the proper type.

> }
>
>
> /* TU3.c */
>
> void foo(struct { int a; });
> void baz()
> {
> struct { int a; } Y;
> Y.a=0;
> foo(Y);


Same problem as before: Two untagged structs in the same
translation unit are two distinct types.

> }
>
> If I understood what you said upthread correctly, this will work just
> fine, though if foo were actually defined in TU2.c then there'd be a
> type-incompatibility and TU2.c wouldn't compile.
>
> Doesn't this force binary compatibility between objects of any unnamed
> types struct { int a; } in different translation units? (But not
> necessary between an object of a type struct { int a; } and an object
> of a type struct { int b; } ?)


I think you should re-read 6.2.7p1, and then if necessary
take a deep breath and read it yet again. Question 11.5 in
the FAQ may also be ful.

--
Eric Sosman
esosman@ieee-dot-org.invalid
  Réponse avec citation
 
Page generated in 0,06792 seconds with 9 queries