Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C Programming > Memory layout in unions

Reply
Thread Tools

Memory layout in unions

 
 
qarnos
Guest
Posts: n/a
 
      01-10-2009
Hi, people.

I just have a quick question for people more familiar with the C
standards than myself.

If I have a union with an anonymous struct, as follows:

union my_union
{
unsigned int ccount[2];

struct
{
unsigned int rcount;
unsigned int lcount;
};
};

Am I guaranteed than ccount[0] will map to rcount and ccount[1] to
lcount? Or is the compiler allowed to re-order the struct members?

Thanks for any assistance.
 
Reply With Quote
 
 
 
 
just.a.garbageman@gmail.com
Guest
Posts: n/a
 
      01-10-2009
On Jan 10, 12:02*pm, qarnos <(E-Mail Removed)> wrote:
> Hi, people.
>
> I just have a quick question for people more familiar with the C
> standards than myself.
>
> If I have a union with an anonymous struct, as follows:
>
> union my_union
> {
> * * unsigned int ccount[2];
>
> * * struct
> * * {
> * * * * unsigned int rcount;
> * * * * unsigned int lcount;
> * * };
>
> };
>
> Am I guaranteed than ccount[0] will map to rcount and ccount[1] to
> lcount? Or is the compiler allowed to re-order the struct members?


The compiler is not allowed to reorder the struct members if they're
not bitfields.
 
Reply With Quote
 
 
 
 
Tomás Ó hÉilidhe
Guest
Posts: n/a
 
      01-10-2009
qarnos wrote:

> union my_union
> {
> unsigned int ccount[2];
>
> struct
> {
> unsigned int rcount;
> unsigned int lcount;
> };
> };
>
> Am I guaranteed than ccount[0] will map to rcount and ccount[1] to
> lcount? Or is the compiler allowed to re-order the struct members?



You'll never have padding between elements in an array, however you /
might/ have padding between members in a struct.

In your example, which uses "int", it's extremely unlikely that
there'll be padding between the struct members (in fact there might
not be a single compiler on the planet that would put in padding
between ints).
 
Reply With Quote
 
Tomás Ó hÉilidhe
Guest
Posts: n/a
 
      01-10-2009
On Jan 10, 6:03*pm, (E-Mail Removed) wrote:

> The compiler is not allowed to reorder the struct members if they're
> not bitfields.



I'm open to correction here, but I was certain that struct members had
to be lain out in the order you specify. That is to say, if you have:

struct Type { char a; int b; double c; void *d; };

Then the following is true:

offsetof(Type,d) > offsetof(Type,c) > offsetof(Type,b) > offsetof
(Type,a)

Again I'm open to correction.

 
Reply With Quote
 
qarnos
Guest
Posts: n/a
 
      01-10-2009
On Jan 10, 10:23*pm, Tomás Ó hÉilidhe <(E-Mail Removed)> wrote:
> qarnos wrote:
> > union my_union
> > {
> > * * unsigned int ccount[2];

>
> > * * struct
> > * * {
> > * * * * unsigned int rcount;
> > * * * * unsigned int lcount;
> > * * };
> > };

>
> > Am I guaranteed than ccount[0] will map to rcount and ccount[1] to
> > lcount? Or is the compiler allowed to re-order the struct members?

>
> You'll never have padding between elements in an array, however you /
> might/ have padding between members in a struct.
>
> In your example, which uses "int", it's extremely unlikely that
> there'll be padding between the struct members (in fact there might
> not be a single compiler on the planet that would put in padding
> between ints).


So basically what you are saying is that in the "real world", no
compiler will insert padding, but at the technical level it is not
100% guaranteed by the standard?
 
Reply With Quote
 
Tomás Ó hÉilidhe
Guest
Posts: n/a
 
      01-10-2009
On Jan 10, 6:46*pm, qarnos <(E-Mail Removed)> wrote:

> So basically what you are saying is that in the "real world", no
> compiler will insert padding, but at the technical level it is not
> 100% guaranteed by the standard?



Correct, that's what I'm saying. The definition of "mammal" allows for
a mammalian species to have an odd number of legs, but I've yet to see
such a species.

If you were to have something like "char" though instead of "int",
you'll find a lot of compilers will put in padding.
 
Reply With Quote
 
Keith Thompson
Guest
Posts: n/a
 
      01-10-2009
qarnos <(E-Mail Removed)> writes:
> I just have a quick question for people more familiar with the C
> standards than myself.
>
> If I have a union with an anonymous struct, as follows:
>
> union my_union
> {
> unsigned int ccount[2];
>
> struct
> {
> unsigned int rcount;
> unsigned int lcount;
> };
> };
>
> Am I guaranteed than ccount[0] will map to rcount and ccount[1] to
> lcount? Or is the compiler allowed to re-order the struct members?


If you use a conforming compiler, your only guarantee is that you'll
get a diagnostic message. If you don't get one, your compiler is not
conforming, or at least you didn't run it in a conforming mode. (gcc
is not conforming by default; try "-ansi -pedantic".)

Standard C does not allow anonymous struct members.

But let's make it non-anonymous (that wasn't your main point anyway):

union my_union {
unsigned int ccount[2];
struct {
unsigned int rcount;
unsigned int lcount;
} foo;
};

union my_union obj;

The standard guarantees that members of a struct (other than bit
fields) are laid out in the order in which they're declared, that the
first member of a struct is at offset 0, and that each member of a
union is at offset 0. Thus obj.ccount[0] and obj.foo.rcount are
guaranteed to occupy the same location.

Compilers are allowed to insert arbitrary padding between struct
members and/or after the last member. Normally this is done for
alignment purposes, but the standard doesn't restrict it; a perverse
compiler could insert as much padding as it likes. I don't think it's
possible for padding between rcount and lcount to be necessary for
alignment purposes, so obj.ccount[1] and obj.foo.lcount almost
certainly occupy the same location, but the standard doesn't actually
guarantee it.

Furthermore, though unions are commonly used to treat a given chunk of
memory as if it were of two different types, the standard doesn't
actually support this usage except in a few cases. Storing a value in
one member of a union and then reading a value from another member is,
in most cases, undefined behavior. It's a common enough usage that
any compiler will probably let you get away with it, but even if the
obj.ccount[0] and obj.foo.rcount occupy the same location, an
optimizing compiler could theoretically rearrange the code so that it
doesn't behave that way. For example:

int n = 42;
printf("%d\n", n);
/* The generated code could use a literal 42 rather than
re-loading the value of n */

/* declarations as above */
obj.foo.rcount = 42;
obj.ccount[0] = 137;
printf("%d\n", obj.foo.rcount);
/* The generated code could use a literal 42 rather than
re-loading the value of obj.foo.rcount. Since the value must
be 42 unless you've done something that invokes undefined
behavior, this is a valid optimization. */

*But* there's a lot of code out there that does this kind of thing,
even though the standard doesn't support it, and it's unlikely that a
compiler vendor is going to break such code.

Having said all that, there is a way to do what you want that's fully
supported by the standard:

struct my_struct {
unsigned int ccount[2];
};
#define rcount ccount[0]
#define lcount ccount[1]
struct my_struct obj;

Now obj.rcount actually *means* obj.ccount[0], and obj.lcount means
obj.ccount[1].

--
Keith Thompson (The_Other_Keith) http://www.velocityreviews.com/forums/(E-Mail Removed) <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
 
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
Choosing Layout: Css-Layout or Table-Layout hpourfard@gmail.com ASP .Net 1 06-19-2006 10:06 AM
CSS Layout question - how to duplicate a table layout with CSS Eric ASP .Net 4 12-24-2004 04:54 PM
Oppinion regarding grid layout vs flow layout NWx ASP .Net 4 02-19-2004 08:56 PM
Converting from grid layout to flow layout. RobertH ASP .Net 1 11-04-2003 12:43 AM
DataList inside a Grid Layout Panel (<DIV>) item layout problem Rick Spiewak ASP .Net 3 08-26-2003 04:22 AM



Advertisments