Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C Programming > Getting sizeof an anonymous struct declared inside a union

Reply
Thread Tools

Getting sizeof an anonymous struct declared inside a union

 
 
David Resnick
Guest
Posts: n/a
 
      10-17-2007
I'm faced with a header with anonymous structures declared inside a
union like this:

union msg {
struct {
int a;
int b;
} s1;

struct {
char c;
double d;
double e;
} s2;
};

I want to apply the sizeof operator to one of these structs.
Changing the header is not currently an option, alas.

I currently can see two ways to do this as shown in this test program:

#include <stdio.h>
/* above union declaration here */
int main(void)
{
union msg foo;
printf("%lu\n", (unsigned long)sizeof(foo.s1));
printf("%lu\n", (unsigned long)sizeof(((union msg*)(NULL))->s2));

return 0;
}

Is the second legitimate? It compiles without complaint, but looks
dodgy.
I hate to create a fake instance of the union just to apply the sizeof
operator.
Or is there another way?

Thanks,
-David

 
Reply With Quote
 
 
 
 
vipvipvipvip.ru@gmail.com
Guest
Posts: n/a
 
      10-17-2007
On Oct 17, 6:07 pm, David Resnick <(E-Mail Removed)> wrote:
> Is the second legitimate? It compiles without complaint, but looks
> dodgy.

Yes it is.
Consider the following:
int *p;
printf("sizeof(*p) == sizeof(int) == %zu\n", sizeof *p);
This would've been invalid code if what p pointed to was really
accessed.

 
Reply With Quote
 
 
 
 
Ben Bacarisse
Guest
Posts: n/a
 
      10-17-2007
David Resnick <(E-Mail Removed)> writes:

> I'm faced with a header with anonymous structures declared inside a
> union like this:
>
> union msg {
> struct {
> int a;
> int b;
> } s1;
>
> struct {
> char c;
> double d;
> double e;
> } s2;
> };
>
> I want to apply the sizeof operator to one of these structs.
> Changing the header is not currently an option, alas.
>
> I currently can see two ways to do this as shown in this test program:
>
> #include <stdio.h>
> /* above union declaration here */
> int main(void)
> {
> union msg foo;
> printf("%lu\n", (unsigned long)sizeof(foo.s1));
> printf("%lu\n", (unsigned long)sizeof(((union msg*)(NULL))->s2));
>
> return 0;
> }
>
> Is the second legitimate?


I think so, yes. Unless the union contains a variable length array,
the operand of sizeof is not evaluated.

> It compiles without complaint, but looks
> dodgy.
> I hate to create a fake instance of the union just to apply the sizeof
> operator.
> Or is there another way?


You can use a compound literal (new in C99) which won't actually
'make' anything either:

sizeof (union msg){{0,0}}.s2;

but this requires you to know how to initialise a 'union msg' (so the
code changes if the structure changes) and you need C99. Since you
carefully cast sizeof's result to unsigned long (rather then using
%zu) I suspect you are not using C99.

--
Ben.
 
Reply With Quote
 
=?iso-2022-kr?q?=1B=24=29CHarald_van_D=0E=29=26=0Fk?=
Guest
Posts: n/a
 
      10-17-2007
On Wed, 17 Oct 2007 16:44:36 +0100, Ben Bacarisse wrote:
> You can use a compound literal (new in C99) which won't actually 'make'
> anything either:
>
> sizeof (union msg){{0,0}}.s2;
>
> but this requires you to know how to initialise a 'union msg' (so the
> code changes if the structure changes)


All object and incomplete types can be initialised to {0}, whether
they're arrays, structures, unions, or scalars.

sizeof (int) {0} ==
sizeof (int)
sizeof (int [2]) {0} ==
sizeof (int [2])
sizeof (union { struct { union { int m; } u; } s; }) {0} ==
sizeof (union { struct { union { int m; } u; } s; })
 
Reply With Quote
 
Keith Thompson
Guest
Posts: n/a
 
      10-17-2007
http://www.velocityreviews.com/forums/(E-Mail Removed) writes:
> On Oct 17, 6:07 pm, David Resnick <(E-Mail Removed)> wrote:
>> Is the second legitimate? It compiles without complaint, but looks
>> dodgy.

> Yes it is.
> Consider the following:
> int *p;
> printf("sizeof(*p) == sizeof(int) == %zu\n", sizeof *p);
> This would've been invalid code if what p pointed to was really
> accessed.


Yes, it would have. Fortunately, the argument to sizeof is never
evaluated unless it's a VLA.

--
Keith Thompson (The_Other_Keith) (E-Mail Removed) <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
 
Reply With Quote
 
Ben Bacarisse
Guest
Posts: n/a
 
      10-17-2007
Harald van Dijk <(E-Mail Removed)> writes:

> On Wed, 17 Oct 2007 16:44:36 +0100, Ben Bacarisse wrote:
>> You can use a compound literal (new in C99) which won't actually 'make'
>> anything either:
>>
>> sizeof (union msg){{0,0}}.s2;
>>
>> but this requires you to know how to initialise a 'union msg' (so the
>> code changes if the structure changes)

>
> All object and incomplete types can be initialised to {0}, whether
> they're arrays, structures, unions, or scalars.
>
> sizeof (int) {0} ==
> sizeof (int)
> sizeof (int [2]) {0} ==
> sizeof (int [2])
> sizeof (union { struct { union { int m; } u; } s; }) {0} ==
> sizeof (union { struct { union { int m; } u; } s; })


Duh! I tried that, and concluded that the rules must be different for
compound literals, but it was just the compiler giving me a helpful
warning.

--
Ben.
 
Reply With Quote
 
David Thompson
Guest
Posts: n/a
 
      10-29-2007
On Wed, 17 Oct 2007 16:36:44 +0000 (UTC), $)CHarald van D)&k
<(E-Mail Removed)> wrote:

> On Wed, 17 Oct 2007 16:44:36 +0100, Ben Bacarisse wrote:
> > You can use a compound literal (new in C99) which won't actually 'make'
> > anything either:
> >
> > sizeof (union msg){{0,0}}.s2;
> >
> > but this requires you to know how to initialise a 'union msg' (so the
> > code changes if the structure changes)

>
> All object and incomplete types can be initialised to {0}, whether
> they're arrays, structures, unions, or scalars.
>

Object types yes, and array of unknown size (but not VLA); but not the
other incomplete types: tag-only struct/union, and void.

- formerly david.thompson1 || achar(64) || worldnet.att.net
 
Reply With Quote
 
=?iso-2022-kr?q?=1B=24=29CHarald_van_D=0E=29=26=0Fk?=
Guest
Posts: n/a
 
      10-29-2007
On Mon, 29 Oct 2007 01:02:24 +0000, David Thompson wrote:
> On Wed, 17 Oct 2007 16:36:44 +0000 (UTC), $)CHarald van D)&k
> <(E-Mail Removed)> wrote:
>> All object and incomplete types can be initialised to {0}, whether
>> they're arrays, structures, unions, or scalars.
>>

> Object types yes, and array of unknown size (but not VLA); but not the
> other incomplete types: tag-only struct/union, and void.


You can't define objects of undefined struct/union types or of void type
anyway, so whether the initialiser would work if you could doesn't really
matter, but VLAs are a definite exception. Thanks, I'll try to remember
that.
 
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
union inside struct - how to get rid of "ISO C" warning? Andreas Eibach C Programming 5 10-06-2009 10:39 AM
union inside struct - how to get rid of "ISO C" warning? Andreas Eibach C Programming 4 10-06-2009 02:19 AM
Union with anonymous struct JKop C++ 5 10-26-2004 03:54 PM
union in struct without union name Peter Dunker C Programming 2 04-26-2004 07:23 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