|
|
|
|
||||||
![]() |
|
|
LinkBack | Outils de la discussion |
|
|
#1 (permalink) |
|
Messages: n/a
Hébergeur: |
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 |
|
|
|
#2 (permalink) |
|
Messages: n/a
Hébergeur: |
On Oct 17, 6:07 pm, David Resnick <lndresn...@gmail.com> 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. |
|
|
|
#3 (permalink) |
|
Messages: n/a
Hébergeur: |
David Resnick <lndresnick@gmail.com> 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. |
|
|
|
#4 (permalink) |
|
Messages: n/a
Hébergeur: |
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; }) |
|
|
|
#5 (permalink) |
|
Messages: n/a
Hébergeur: |
vipvipvipvip.ru@gmail.com writes:
> On Oct 17, 6:07 pm, David Resnick <lndresn...@gmail.com> 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) kst-u@mib.org <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" |
|
|
|
#6 (permalink) |
|
Messages: n/a
Hébergeur: |
Harald van Dijk <truedfx@gmail.com> 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 ful warning. -- Ben. |
|
|
|
#7 (permalink) |
|
Messages: n/a
Hébergeur: |
On Wed, 17 Oct 2007 16:36:44 +0000 (UTC), $)CHarald van D)&k
<truedfx@gmail.com> 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 |
|
|
|
#8 (permalink) |
|
Messages: n/a
Hébergeur: |
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 > <truedfx@gmail.com> 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. |
|
![]() |
| Outils de la discussion | |
|
|