Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
| Date | 2013-01-20 13:21 +1100 |
|---|---|
| From | Russell Shaw <rjshawN_o@s_pam.netspace.net.au> |
| Newsgroups | comp.lang.c |
| Subject | Re: Struct assignment |
| References | <u0fqs9-929.ln1@main.anatron.com.au> <kde706$3t0$1@dont-email.me> <simqs9-ue9.ln1@main.anatron.com.au> <kdeik4$b8s$1@dont-email.me> |
| Message-ID | <0u0ss9-jv4.ln1@main.anatron.com.au> (permalink) |
| Organization | Unlimited download news at news.astraweb.com |
On 20/01/13 03:45, Shao Miller wrote:
> On 1/19/2013 09:18, Russell Shaw wrote:
>> On 20/01/13 00:27, Eric Sosman wrote:
>>> On 1/19/2013 7:09 AM, Russell Shaw wrote:
>>>> Hi,
>>>> In gcc-4.7 C99, i get an error (in a function scope):
>>>>
>>>> struct {
>>>> int a;
>>>> } sa;
>>>>
>>>> struct {
>>>> int a;
>>>> } sb;
>>>>
>>>> sb = sa;
>>>>
>>>> error: incompatible types when assigning to type 'struct <anonymous>'
>>>> from type 'struct <anonymous>'
>>>>
>>>>
>>>> ISO/IEC 9899:201x Committee Draft -- August 11, 2008 WG14/N1336
>>>>
>>>> 6.5.16.1 Simple assignment
>>>> Para 1
>>>> -- the left operand has a qualified or unqualified version of a
>>>> structure or union type compatible with the type of the right;
>>>>
>>>>
>>>> 6.2.7 Compatible type and composite type
>>>> Para 1
>>>> Two types have compatible type if their types are the same. Additional
>>>> rules for determining whether two types are compatible are described in
>>>> 6.7.2 for type specifiers, in 6.7.3 for type qualifiers, and in 6.7.5
>>>> for declarators.48) Moreover, two structure, union, or enumerated types
>>>> declared in separate translation units are compatible if their tags and
>>>> members satisfy the following requirements: If one is declared with a
>>>> tag, the other shall be declared with the same tag. If both are complete
>>>> types, 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, and such that
>>>> if one member of a corresponding pair is declared with a name, the other
>>>> member is declared with the same name. For two structures, corresponding
>>>> members shall be declared in the same order. For two structures or
>>>> unions, corresponding bit-fields shall have the same widths. For two
>>>> enumerations, corresponding members shall have the same values.
>>>>
>>>>
>>>> The above mentions "separate translation units", but i don't see why the
>>>> error should happen.
>>>
>>> Um, er, because your `sa' and `sb' are not in separate
>>> translation units? And hence aren't compatible?
>>>
>>> The fact that two types look the same (as yours do) doesn't
>>> mean they actually are the same; it's just a coincidence of
>>> their representation. On many systems `int' and `long' have
>>> the same representation and even the same behavior, yet they
>>> are distinct types nonetheless. (Incompatible types, too,
>>> though implicit conversions often disguise the fact.)
>>>
>>> Have you ever run into the (in)famous "struct declaration
>>> in parameter list" problem (FAQ Question 2.5)? That's very much
>>> like what's happening here: Having written a type declaration
>>> without a name (tag) or alias (typedef), you have no way to
>>> designate that same type again.
>>
>> Why should it matter that the second struct is "declared" in a separate
>> translation unit?
>
> The usual tradition for two translation units to use the same programmer-defined
> type is for them to both #include a header that defines that type. But during
> translation, it's not really the header that defines the type, it's the
> translation unit. So we need to ask, "Is the type used in TU A the same as in TU
> B?" The discussion about compatible types answers this question.
When both sa and sb are declared in the one common header, sb = sa still gives
the same error.
I just don't see why the point about being compatible between different
translation units is made, when the same header declaration is going to be used
in both anyway.
>> To be able to do the assignment, you have to #include
>> that second declaration in to the first file anyway.
>>
>
> You don't have to #include anything. You can copy and paste the type's
> definition manually, or the object's or function's declaration/definition.
>
>> It's easy to write a compiler to do that assignment deterministically,
>> so why's it not allowed?
>>
>> p.6.2.7 describes the compatability for structs in separate translation
>> units, but says nothing (ie, does not forbid) about assignments in the
>> same translation unit.
>
> How can you argue that their types are the same in this circumstance? Since the
> type has no associated identifier, how can you be sure? Please consider another
> simple case (which presents the same issue):
>
> int main(void) {
> if ((struct { int x; } *) 0 == (struct { int x; } *) 0)
> return 0;
> return 0;
> }
>
> How do you know that these types are the same? How do you know how many padding
> bytes these two referenced (pointed-to) types have after their 'x' members? How
> do you know the alignment requirements of the referenced types?
Both types are structurally the same because they're both pointers to structs
that are built the same way.
I'm assuming those two structs are built the same way with the same padding,
because if they weren't, the compiler ABI is then randomly inconsistant.
> Suppose you have:
>
> typedef int tni;
> struct { int size; } apple;
> struct { tni size; } orange;
>
> Should these two objects be considered to have the same type, if we saw these in
> the same translation unit? It could be that the _intention_ is for each to
> belong to a different domain, and the discussion of compatible types helps to
> prevent against accidental crossing of domains.
That's what i'd like to see, but i was trying to figure out how assignments
between them can be done if they come from different translation units.
I cannot devise how sb = sa can be found in any source, where sb and sa have
separate struct declarations.
The only use case i can think of is:
Translation unit1:
// tu1.h header:
struct {
int a;
} sb;
struct sb *str_new(void);
// tu1.c
struct {
int a;
} sa;
struct sa *str_new(void)
{
struct sa *str = malloc(sizeof(struct sa));
return str;
}
Back to comp.lang.c | Previous | Next — Previous in thread | Next in thread | Find similar | Unroll thread
Struct assignment Russell Shaw <rjshawN_o@s_pam.netspace.net.au> - 2013-01-19 23:09 +1100
Re: Struct assignment Eric Sosman <esosman@comcast-dot-net.invalid> - 2013-01-19 08:27 -0500
Re: Struct assignment Russell Shaw <rjshawN_o@s_pam.netspace.net.au> - 2013-01-20 01:18 +1100
Re: Struct assignment "BartC" <bc@freeuk.com> - 2013-01-19 14:59 +0000
Re: Struct assignment Eric Sosman <esosman@comcast-dot-net.invalid> - 2013-01-19 11:25 -0500
Re: Struct assignment Russell Shaw <rjshawN_o@s_pam.netspace.net.au> - 2013-01-20 12:46 +1100
Re: Struct assignment Bart van Ingen Schenau <bart@ingen.ddns.info.invalid> - 2013-01-20 09:20 +0000
Re: Struct assignment Eric Sosman <esosman@comcast-dot-net.invalid> - 2013-01-20 09:08 -0500
Re: Struct assignment Russell Shaw <rjshawN_o@s_pam.netspace.net.au> - 2013-01-21 12:02 +1100
Re: Struct assignment Eric Sosman <esosman@comcast-dot-net.invalid> - 2013-01-20 22:08 -0500
Re: Struct assignment James Kuyper <jameskuyper@verizon.net> - 2013-01-20 23:21 -0500
Re: Struct assignment James Kuyper <jameskuyper@verizon.net> - 2013-01-21 08:23 -0500
Re: Struct assignment Russell Shaw <rjshawN_o@s_pam.netspace.net.au> - 2013-01-22 13:33 +1100
Re: Struct assignment Russell Shaw <rjshawN_o@s_pam.netspace.net.au> - 2013-01-23 19:53 +1100
Re: Struct assignment Shao Miller <sha0.miller@gmail.com> - 2013-01-19 11:45 -0500
Re: Struct assignment Russell Shaw <rjshawN_o@s_pam.netspace.net.au> - 2013-01-20 13:21 +1100
Re: Struct assignment Shao Miller <sha0.miller@gmail.com> - 2013-01-20 01:06 -0500
Re: Struct assignment Russell Shaw <rjshawN_o@s_pam.netspace.net.au> - 2013-01-20 18:03 +1100
Re: Struct assignment glen herrmannsfeldt <gah@ugcs.caltech.edu> - 2013-01-19 19:18 +0000
Re: Struct assignment James Kuyper <jameskuyper@verizon.net> - 2013-01-19 15:22 -0500
Re: Struct assignment Shao Miller <sha0.miller@gmail.com> - 2013-01-19 15:47 -0500
Re: Struct assignment Eric Sosman <esosman@comcast-dot-net.invalid> - 2013-01-19 17:56 -0500
Re: Struct assignment Tim Rentsch <txr@alumni.caltech.edu> - 2013-01-20 12:12 -0800
Re: Struct assignment falk@rahul.net (Edward A. Falk) - 2013-01-19 23:41 +0000
Re: Struct assignment glen herrmannsfeldt <gah@ugcs.caltech.edu> - 2013-01-20 01:01 +0000
Re: Struct assignment James Kuyper <jameskuyper@verizon.net> - 2013-01-19 20:53 -0500
Re: Struct assignment Tim Rentsch <txr@alumni.caltech.edu> - 2013-01-20 12:03 -0800
csiph-web