Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C Programming > Re: Struct assignment

Reply
Thread Tools

Re: Struct assignment

 
 
James Kuyper
Guest
Posts: n/a
 
      01-21-2013
On 01/20/2013 08:02 PM, Russell Shaw wrote:
> On 21/01/13 01:08, Eric Sosman wrote:
>> On 1/19/2013 8:46 PM, Russell Shaw wrote:
>>> [... two "identical" struct types are incompatible ...]
>>>
>>> The problem is that if you #include the declaration of an anonymous
>>> struct sa from a separate translation unit, then the compiler complains
>>> about sb = sa.

>>
>> I don't understand this. A "translation unit" is all of
>> the source the compiler sees at one time: The original source
>> file, all the files and headers it #includes, all the files and
>> headers they in turn #include, all macros defined on compiler
>> command lines or whatever, ... If you #include a declaration,
>> that declaration is part of *the* translation unit; it is not
>> an interloper from "a separate translation unit."

>
> Precisely. Because of that problem, i could not see how declarations from
> separate translation units should be compatible, when including a header with
> the second declaration now becomes a part of the first translation unit anyway,
> thus making the point mute.


I'm not sure I understand your objection. #include is a red herring
here; all that matters is what the translation units contain after all
#include directives have been processed. Therefore, I'll give an example
involving no shared header files (which would, in general, be a bad
coding practice - but then, IMO, so is the use of unnamed struct types).

file declared.c:
extern struct {unsigned u:4; _Alignas(long long) double d;} a, b;

file defined.c:
struct {unsigned u:4; _Alignas(_Alignof(long long)) double d;} a, b;

In each file, 'a' is compatible with 'b', despite the fact that they
both have an anonymous struct type, because the same anonymous struct
definition was used to declare both objects.
The one definition rule requires that the external declarations in
declared.c be compatible with the definitions in defined.c, and they
are, but for a different reason: the definitions of the
struct types in the two different translation units meet all of the
requirements of 6.2.7p1:

"If one is declared with a tag, the other shall be declared with the
same tag." - neither one is declared with a tag.

"If both are completed anywhere within their respective translation
units, then the following additional requirements apply: there shall
be a one-to-one correspondence between their members such that each pair
of corresponding members are declared with compatible types; ..." -
There is such a correspondence - the types of the corresponding members
are not merely compatible, but identical.

"... if one member of the pair is declared with an alignment specifier,
the other is declared with an equivalent alignment specifier; ..."
- 'd' is declared with equivalent alignment specifiers in both struct
definitions.

"... and if one member of the pair is declared with a name, the other is
declared with the same name. ..." - for every pair, the names are in
fact the same.

"For two structures, corresponding members shall be declared in the same
order." - they are declared in the same order.

"For two structures or unions, corresponding bit-fields shall have the
same widths." - 'u' has the same width in both structure definitions.

The key point is that these requirements only render compatible struct
definitions that appear in different translation units. Therefore, even
though the following line define struct types that also meet all of
those requirements, because they occur in the same translation unit,
they define incompatible struct types:

struct {unsigned u:4; _Alignof(long long) double d;} a;
struct {unsigned u:4; _Alignof(long long) double d;} b;

This may seem counter-intuitive, but the reason for this difference is
that it was not considered necessary to extend this specification to
include struct types declared in the same translation unit. The standard
already provides three different ways to define structure objects in the
same translation unit to have compatible types: struct tags, typedefs,
or sharing the same anonymous struct definition, as in my example above.
None of those things would be sufficient to allow declarations of struct
types in different translation units to be compatible - it's only
6.2.7p1 that makes that possible.

Note: I don't agree with this decision; I don't see any advantage to
restricting the guarantee of compatibility to structs defined in
different translation units. However, that is what the standard specifies.

> I'll go with the interpretation as stated in this group, because it makes for
> less complication in the compiler, and is safer to use.


I'm not sure what you consider to be "the interpretation as stated in
this group". Is it compatible with what I've said above?
--
James Kuyper

--
James Kuyper
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Can *common* struct-members of 2 different struct-types, that are thesame for the first common members, be accessed via pointer cast to either struct-type? John Reye C Programming 28 05-08-2012 12:24 AM
Rationale for struct assignment and no struct comparison Noob C Programming 25 12-09-2009 08:56 AM
Assignment operator self-assignment check Chris C++ 34 09-26-2006 04:26 AM
Augument assignment versus regular assignment nagy Python 36 07-20-2006 07:24 PM
struct my_struct *p = (struct my_struct *)malloc(sizeof(struct my_struct)); Chris Fogelklou C Programming 36 04-20-2004 08:27 AM



Advertisments