473,387 Members | 1,641 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,387 software developers and data experts.

Getting sizeof an anonymous struct declared inside a union

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

Oct 17 '07 #1
7 8816
On Oct 17, 6:07 pm, David Resnick <lndresn...@gmail.comwrote:
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.

Oct 17 '07 #2
David Resnick <ln********@gmail.comwrites:
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.
Oct 17 '07 #3
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; })
Oct 17 '07 #4
vi*************@gmail.com writes:
On Oct 17, 6:07 pm, David Resnick <lndresn...@gmail.comwrote:
>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) ks***@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"
Oct 17 '07 #5
Harald van Dijk <tr*****@gmail.comwrites:
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.
Oct 17 '07 #6
On Wed, 17 Oct 2007 16:36:44 +0000 (UTC), $)CHarald van D)&k
<tr*****@gmail.comwrote:
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
Oct 29 '07 #7
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
<tr*****@gmail.comwrote:
>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.
Oct 29 '07 #8

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

5
by: JKop | last post by:
You know how from time to time, you want to have an array which you can access via: array_name; But also, you'd like the more user-friendly option: array_name.element1 array_name.element2
5
by: Martin Vorbrodt | last post by:
here's what i have: struct SCSI_CDB { .... union { struct { unsigned char address0; unsigned char address1; unsigned char address2;
7
by: Kieran Simkin | last post by:
I have in my project in main.c a number of arrays defined like this (outside of any functions): char muser, mpass; I'm declaring them in a number of other .c files (inside functions) like this:...
1
by: qwerty2_reverse_iterator | last post by:
Is this a bug with the ms compiler (V7.1)? (It seems so at least.) I get errors when I don't initialize all the const pointer fields of an anonymous union in a struct. Example: //T2.h...
18
by: Mockey Chen | last post by:
My friend ask me a question as following: give a union SU define as: typedef union _SU { short x; struct y{ char a; short b; char c;
32
by: moleskyca1 | last post by:
This may be stupid question, but why is sizeof(Base) == 1 in: int main(int argc, char* argv) { class Base { }; cout << sizeof(Base) << endl; return 0; }
9
by: CptDondo | last post by:
I am missing something about structure declarations.... I am trying to get the size of a structure member using sizeof. my xml.h file (beware of line wrap): struct fieldSchedule_t { uint8_t...
40
by: Boltar | last post by:
Hi Why - using gcc on linux - does this return 0 in C but returns 1 in C+ +? I don't get it. #include <stdio.h> struct foo { };
3
by: SRK | last post by:
Hi, I wanted to use an anonymous union within an structure something like below - struct Test { union { std::string user; //char user; std::string role; //char role;
0
by: taylorcarr | last post by:
A Canon printer is a smart device known for being advanced, efficient, and reliable. It is designed for home, office, and hybrid workspace use and can also be used for a variety of purposes. However,...
0
by: aa123db | last post by:
Variable and constants Use var or let for variables and const fror constants. Var foo ='bar'; Let foo ='bar';const baz ='bar'; Functions function $name$ ($parameters$) { } ...
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.