Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.c > #158366 > unrolled thread
| Started by | Steve Keller <keller.steve@gmx.de> |
|---|---|
| First post | 2021-01-15 09:45 +0100 |
| Last post | 2021-01-15 19:48 -0800 |
| Articles | 13 — 8 participants |
Back to article view | Back to comp.lang.c
Anonymous unions Steve Keller <keller.steve@gmx.de> - 2021-01-15 09:45 +0100
Re: Anonymous unions "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> - 2021-01-15 01:41 -0800
Re: Anonymous unions Sumireko Usami <usasumi3hu@gmail.com> - 2021-01-15 13:00 +0100
Re: Anonymous unions "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> - 2021-01-16 14:04 -0800
Re: Anonymous unions Bart <bc@freeuk.com> - 2021-01-15 12:38 +0000
Re: Anonymous unions Bonita Montero <Bonita.Montero@gmail.com> - 2021-01-15 14:18 +0100
Re: Anonymous unions Thiago Adams <thiago.adams@gmail.com> - 2021-01-15 06:37 -0800
Re: Anonymous unions "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> - 2021-01-16 14:05 -0800
Re: Anonymous unions "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> - 2021-01-16 14:08 -0800
Re: Anonymous unions Andrey Tarasevich <andreytarasevich@hotmail.com> - 2021-01-16 19:04 -0800
Re: Anonymous unions "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> - 2021-01-16 19:32 -0800
Re: Anonymous unions Tim Rentsch <tr.17687@z991.linuxsc.com> - 2021-01-15 10:10 -0800
Re: Anonymous unions Andrey Tarasevich <andreytarasevich@hotmail.com> - 2021-01-15 19:48 -0800
| From | Steve Keller <keller.steve@gmx.de> |
|---|---|
| Date | 2021-01-15 09:45 +0100 |
| Subject | Anonymous unions |
| Message-ID | <rtrkml$1de$1@gioia.aioe.org> |
I want to define something like the following:
struct foo {
int a;
int b;
};
struct bar {
...;
union {
int a;
struct foo f;
};
...;
};
Having a struct bar b, is it correct and that b.a and b.f.a is always
the same object? I.e. will the following always work?
struct bar b;
struct foo f = { 42, 21 };
b.f = f;
if (b.a == 42)
puts("worked");
I have tried with gcc and it works. But does standard C guarantee this?
Steve
[toc] | [next] | [standalone]
| From | "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> |
|---|---|
| Date | 2021-01-15 01:41 -0800 |
| Message-ID | <rtro0d$19gs$2@gioia.aioe.org> |
| In reply to | #158366 |
On 1/15/2021 12:45 AM, Steve Keller wrote:
> I want to define something like the following:
>
> struct foo {
> int a;
> int b;
> };
>
> struct bar {
> ...;
> union {
> int a;
> struct foo f;
> };
> ...;
> };
>
> Having a struct bar b, is it correct and that b.a and b.f.a is always
> the same object? I.e. will the following always work?
>
> struct bar b;
> struct foo f = { 42, 21 };
> b.f = f;
> if (b.a == 42)
> puts("worked");
>
> I have tried with gcc and it works. But does standard C guarantee this?
IIRC, anonymous unions are a gnu extension. But then again, they might
be in C11. Need to check.
[toc] | [prev] | [next] | [standalone]
| From | Sumireko Usami <usasumi3hu@gmail.com> |
|---|---|
| Date | 2021-01-15 13:00 +0100 |
| Message-ID | <92fdca10-5bd8-18b3-065b-f26301c21418@gmail.com> |
| In reply to | #158368 |
On 2021-01-15 10:41, Chris M. Thomasson wrote:
> On 1/15/2021 12:45 AM, Steve Keller wrote:
>> I want to define something like the following:
>>
>> struct foo {
>> int a;
>> int b;
>> };
>>
>> struct bar {
>> ...;
>> union {
>> int a;
>> struct foo f;
>> };
>> ...;
>> };
>
>
>>
>> Having a struct bar b, is it correct and that b.a and b.f.a is always
>> the same object? I.e. will the following always work?
>>
>> struct bar b;
>> struct foo f = { 42, 21 };
>> b.f = f;
>> if (b.a == 42)
>> puts("worked");
>>
>> I have tried with gcc and it works. But does standard C guarantee this?
>
> IIRC, anonymous unions are a gnu extension. But then again, they might
> be in C11. Need to check.
>
Seems that anonymous unions are in C11.
https://en.cppreference.com/w/c/language/union#Explanation
[toc] | [prev] | [next] | [standalone]
| From | "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> |
|---|---|
| Date | 2021-01-16 14:04 -0800 |
| Message-ID | <rtvnt8$v2$1@gioia.aioe.org> |
| In reply to | #158369 |
On 1/15/2021 4:00 AM, Sumireko Usami wrote:
> On 2021-01-15 10:41, Chris M. Thomasson wrote:
>> On 1/15/2021 12:45 AM, Steve Keller wrote:
>>> I want to define something like the following:
>>>
>>> struct foo {
>>> int a;
>>> int b;
>>> };
>>>
>>> struct bar {
>>> ...;
>>> union {
>>> int a;
>>> struct foo f;
>>> };
>>> ...;
>>> };
>>
>>
>>>
>>> Having a struct bar b, is it correct and that b.a and b.f.a is always
>>> the same object? I.e. will the following always work?
>>>
>>> struct bar b;
>>> struct foo f = { 42, 21 };
>>> b.f = f;
>>> if (b.a == 42)
>>> puts("worked");
>>>
>>> I have tried with gcc and it works. But does standard C guarantee this?
>>
>> IIRC, anonymous unions are a gnu extension. But then again, they might
>> be in C11. Need to check.
>>
>
> Seems that anonymous unions are in C11.
> https://en.cppreference.com/w/c/language/union#Explanation
Indeed they are.
[toc] | [prev] | [next] | [standalone]
| From | Bart <bc@freeuk.com> |
|---|---|
| Date | 2021-01-15 12:38 +0000 |
| Message-ID | <i1gMH.873535$b5kb.224574@fx15.ams4> |
| In reply to | #158368 |
On 15/01/2021 09:41, Chris M. Thomasson wrote:
> On 1/15/2021 12:45 AM, Steve Keller wrote:
>> I want to define something like the following:
>>
>> struct foo {
>> int a;
>> int b;
>> };
>>
>> struct bar {
>> ...;
>> union {
>> int a;
>> struct foo f;
>> };
>> ...;
>> };
>
>
>>
>> Having a struct bar b, is it correct and that b.a and b.f.a is always
>> the same object? I.e. will the following always work?
>>
>> struct bar b;
>> struct foo f = { 42, 21 };
>> b.f = f;
>> if (b.a == 42)
>> puts("worked");
>>
>> I have tried with gcc and it works. But does standard C guarantee this?
>
> IIRC, anonymous unions are a gnu extension. But then again, they might
> be in C11. Need to check.
>
They have worked for every compiler I've used for probably 20 years.
Probably C11 makes them official, if not C99.
[toc] | [prev] | [next] | [standalone]
| From | Bonita Montero <Bonita.Montero@gmail.com> |
|---|---|
| Date | 2021-01-15 14:18 +0100 |
| Message-ID | <rts4li$cp0$1@dont-email.me> |
| In reply to | #158370 |
> They have worked for every compiler I've used for probably 20 years. > Probably C11 makes them official, if not C99. Yes, they exist since C11: https://en.cppreference.com/w/c/language/union#Explanation But I'm sure the behaviour is implementation-defined if you use them for aliasing-purposes.
[toc] | [prev] | [next] | [standalone]
| From | Thiago Adams <thiago.adams@gmail.com> |
|---|---|
| Date | 2021-01-15 06:37 -0800 |
| Message-ID | <cae3c3da-9997-4984-9f10-0eff6908ce02n@googlegroups.com> |
| In reply to | #158371 |
On Friday, January 15, 2021 at 10:17:51 AM UTC-3, Bonita Montero wrote:
> > They have worked for every compiler I've used for probably 20 years.
> > Probably C11 makes them official, if not C99.
> Yes, they exist since C11:
> https://en.cppreference.com/w/c/language/union#Explanation
> But I'm sure the behaviour is implementation-defined if you use them
> for aliasing-purposes.
Just for curiosity, Microsoft compiler has an extension that
injects one struct on another. They are unnamed members.
struct point2d { int x,y; };
struct point3d { struct point2d; int z; };
int main(){
struct point3d pt = {.x=1, .y=2 , .z=3};
}
[toc] | [prev] | [next] | [standalone]
| From | "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> |
|---|---|
| Date | 2021-01-16 14:05 -0800 |
| Message-ID | <rtvnut$v2$2@gioia.aioe.org> |
| In reply to | #158373 |
On 1/15/2021 6:37 AM, Thiago Adams wrote:
> On Friday, January 15, 2021 at 10:17:51 AM UTC-3, Bonita Montero wrote:
>>> They have worked for every compiler I've used for probably 20 years.
>>> Probably C11 makes them official, if not C99.
>> Yes, they exist since C11:
>> https://en.cppreference.com/w/c/language/union#Explanation
>> But I'm sure the behaviour is implementation-defined if you use them
>> for aliasing-purposes.
>
>
> Just for curiosity, Microsoft compiler has an extension that
> injects one struct on another. They are unnamed members.
>
> struct point2d { int x,y; };
> struct point3d { struct point2d; int z; };
>
> int main(){
> struct point3d pt = {.x=1, .y=2 , .z=3};
> }
>
Interesting. Never tried it out.
[toc] | [prev] | [next] | [standalone]
| From | "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> |
|---|---|
| Date | 2021-01-16 14:08 -0800 |
| Message-ID | <rtvo50$5cf$1@gioia.aioe.org> |
| In reply to | #158400 |
On 1/16/2021 2:05 PM, Chris M. Thomasson wrote:
> On 1/15/2021 6:37 AM, Thiago Adams wrote:
>> On Friday, January 15, 2021 at 10:17:51 AM UTC-3, Bonita Montero wrote:
>>>> They have worked for every compiler I've used for probably 20 years.
>>>> Probably C11 makes them official, if not C99.
>>> Yes, they exist since C11:
>>> https://en.cppreference.com/w/c/language/union#Explanation
>>> But I'm sure the behaviour is implementation-defined if you use them
>>> for aliasing-purposes.
>>
>>
>> Just for curiosity, Microsoft compiler has an extension that
>> injects one struct on another. They are unnamed members.
>>
>> struct point2d { int x,y; };
>> struct point3d { struct point2d; int z; };
>>
>> int main(){
>> struct point3d pt = {.x=1, .y=2 , .z=3};
>> }
>>
>
>
> Interesting. Never tried it out.
I am assuming that the names of the struct members need to be unique? x,
y, z works well here. So would p0, p1, p2, ... as individual component
parts of a point.
[toc] | [prev] | [next] | [standalone]
| From | Andrey Tarasevich <andreytarasevich@hotmail.com> |
|---|---|
| Date | 2021-01-16 19:04 -0800 |
| Message-ID | <ru09gn$ivd$1@dont-email.me> |
| In reply to | #158373 |
On 1/15/2021 6:37 AM, Thiago Adams wrote:
>
> Just for curiosity, Microsoft compiler has an extension that
> injects one struct on another. They are unnamed members.
>
> struct point2d { int x,y; };
> struct point3d { struct point2d; int z; };
>
> int main(){
> struct point3d pt = {.x=1, .y=2 , .z=3};
> }
>
The idea of that extension is to simplify implementing "inheritance" in
C. It is also available in GCC and Clang under `-fms-extensions`.
--
Best regards,
Andrey Tarasevich
[toc] | [prev] | [next] | [standalone]
| From | "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> |
|---|---|
| Date | 2021-01-16 19:32 -0800 |
| Message-ID | <ru0b51$5c1$1@gioia.aioe.org> |
| In reply to | #158404 |
On 1/16/2021 7:04 PM, Andrey Tarasevich wrote:
> On 1/15/2021 6:37 AM, Thiago Adams wrote:
>>
>> Just for curiosity, Microsoft compiler has an extension that
>> injects one struct on another. They are unnamed members.
>>
>> struct point2d { int x,y; };
>> struct point3d { struct point2d; int z; };
>>
>> int main(){
>> struct point3d pt = {.x=1, .y=2 , .z=3};
>> }
>>
>
> The idea of that extension is to simplify implementing "inheritance" in
> C. It is also available in GCC and Clang under `-fms-extensions`.
>
Nice info. Thanks Andrey.
[toc] | [prev] | [next] | [standalone]
| From | Tim Rentsch <tr.17687@z991.linuxsc.com> |
|---|---|
| Date | 2021-01-15 10:10 -0800 |
| Message-ID | <86zh1anka3.fsf@linuxsc.com> |
| In reply to | #158366 |
Steve Keller <keller.steve@gmx.de> writes:
> I want to define something like the following:
>
> struct foo {
> int a;
> int b;
> };
>
> struct bar {
> ...;
> union {
> int a;
> struct foo f;
> };
> ...;
> };
>
> Having a struct bar b, is it correct and that b.a and b.f.a is
> always the same object? I.e. will the following always work?
>
> struct bar b;
> struct foo f = { 42, 21 };
> b.f = f;
> if (b.a == 42)
> puts("worked");
>
> I have tried with gcc and it works. But does standard C guarantee
> this?
The short answer is yes.
A somewhat longer answer would say that anonymous unions have been
supported in standard C only since C11.
Also, technically the objects b.a and b.f.a are distinct objects,
but they are required to occupy the same area of memory, which is
(part of) what I think you're asking.
Furthermore the read access to b.a is well defined, and required
to work as you expect after the store into b.f. (It is not, as
some may have suggested, implementation-defined behavior.)
Having said that, I might suggest some amount of caution is in
order, because the case is unusual enough so some compilers may
get it wrong. I know that isn't what you are asking, and it may
turn out not to be a problem at all, but it is something that you
may want to take into consideration. Disclaimer: I have no
actual experience with something like this being a problem, and
I would expect any major compiler such as gcc or clang always to
act as you expect. Despite that, a word to the wise seemed in
order.
[toc] | [prev] | [next] | [standalone]
| From | Andrey Tarasevich <andreytarasevich@hotmail.com> |
|---|---|
| Date | 2021-01-15 19:48 -0800 |
| Message-ID | <rttnm3$7m5$1@dont-email.me> |
| In reply to | #158366 |
On 1/15/2021 12:45 AM, Steve Keller wrote:
> I want to define something like the following:
>
> struct foo {
> int a;
> int b;
> };
>
> struct bar {
> ...;
> union {
> int a;
> struct foo f;
> };
> ...;
> };
>
> Having a struct bar b, is it correct and that b.a and b.f.a is always
> the same object? I.e. will the following always work?
>
> struct bar b;
> struct foo f = { 42, 21 };
> b.f = f;
> if (b.a == 42)
> puts("worked");
>
> I have tried with gcc and it works. But does standard C guarantee this?
Depends on what you mean by "this". There are two different matters
involved here:
1. The legality of the "anonymous" declaration.
Anonymous struct/union declarations (no tag, no member declared) are
legal since C11 for both struct and union declarations. Note the "no
tag" requirement. Once your struct/union has a tag the "classic" rules
kick in: you will not be able to declare it inside another struct/union
without declaring a named member of that type.
2. The guarantees about mutual "alignment" of overlapping union members.
In your particular case (i.e. accessing the first `int` member of the
inner struct vs. accessing an adjacent `int` in the same union) you are
safe.
--
Best regards,
Andrey Tarasevich
[toc] | [prev] | [standalone]
Back to top | Article view | comp.lang.c
csiph-web