public inbox for gcc@gcc.gnu.org
 help / color / mirror / Atom feed
* Re: C++ bug in structure packing and inheritance
@ 2001-12-15 23:40 Sam Lantinga
  2001-12-15 23:57 ` Alexandre Oliva
  0 siblings, 1 reply; 4+ messages in thread
From: Sam Lantinga @ 2001-12-15 23:40 UTC (permalink / raw)
  To: gcc

> There seems to be a bug in structure packing in that if you have
> two classes or structures that both inherit from a class with no
> data members, then they will be the wrong size.

> A simple example follows:

> #include <stddef.h>
> #include <stdio.h>

> struct a {
> };

> struct b : public a {
> 	float x;
> 	float y;
> };

> struct c : public a {
> 	b data;
> 	float z;
> };

> main()
> {
> 	printf("size of a = %d (should be 0)\n", sizeof(a));
> 	printf("size of b = %d (should be 8)\n", sizeof(b));
> 	printf("size of c = %d (should be 12)\n", sizeof(c));
> 	printf("offset of c.z = %d (should be 8)\n", offsetof(c,z));
> }

> Sample output with the current CVS of gcc is:
> size of c = 16 (should be 12)

Interestingly, if either b or c are not derived from a, or the order
of b and z within c is swapped, c ends up being the correct size.

I spent a few hours mucking about in class.c, and my uneducated guess
is that the overlay of the base class a followed by the overlay of the
base class a (in b) is what's causing the incorrect sizing of c.

Can anybody confirm or deny this?  GCC gurus, please speak up. :)

Thanks!
	-Sam Lantinga, Software Engineer, Blizzard Entertainment

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: C++ bug in structure packing and inheritance
  2001-12-15 23:40 C++ bug in structure packing and inheritance Sam Lantinga
@ 2001-12-15 23:57 ` Alexandre Oliva
  0 siblings, 0 replies; 4+ messages in thread
From: Alexandre Oliva @ 2001-12-15 23:57 UTC (permalink / raw)
  To: Sam Lantinga; +Cc: gcc

On Dec 16, 2001, Sam Lantinga <slouken@devolution.com> wrote:

>> struct a {
>> };

>> struct b : public a {
>> float x;
>> float y;
>> };

>> struct c : public a {
>> b data;
>> float z;
>> };

>> size of c = 16 (should be 12)

> Interestingly, if either b or c are not derived from a, or the order
> of b and z within c is swapped, c ends up being the correct size.

> I spent a few hours mucking about in class.c, and my uneducated guess
> is that the overlay of the base class a followed by the overlay of the
> base class a (in b) is what's causing the incorrect sizing of c.

It's actually correct.  The sub-object a of class c must have
a different address from the sub-object a of class b, the first data
member of class c.  Thus, data's offset in c must be non-zero.

-- 
Alexandre Oliva   Enjoy Guarana', see http://www.ic.unicamp.br/~oliva/
Red Hat GCC Developer                  aoliva@{cygnus.com, redhat.com}
CS PhD student at IC-Unicamp        oliva@{lsd.ic.unicamp.br, gnu.org}
Free Software Evangelist    *Please* write to mailing lists, not to me

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: C++ bug in structure packing and inheritance
  2001-12-15 15:07 Sam Lantinga
@ 2001-12-15 16:09 ` Daniel Berlin
  0 siblings, 0 replies; 4+ messages in thread
From: Daniel Berlin @ 2001-12-15 16:09 UTC (permalink / raw)
  To: Sam Lantinga; +Cc: gcc



On Sat, 15 Dec 2001, Sam Lantinga wrote:

> There seems to be a bug in structure packing in that if you have
> two classes or structures that both inherit from a class with no
> data members, then they will be the wrong size.

> A simple example follows:
>
> #include <stddef.h>
> #include <stdio.h>
>
> struct a {
> };
>
> struct b : public a {
> 	float x;
> 	float y;
> };
>
> struct c : public a {
> 	b data;
> 	float z;
> };
>
> main()
> {
> 	printf("size of a = %d (should be 0)\n", sizeof(a));
> 	printf("size of b = %d (should be 8)\n", sizeof(b));
> 	printf("size of c = %d (should be 12)\n", sizeof(c));
> 	printf("offset of c.z = %d (should be 8)\n", offsetof(c,z));
> }
>
> Sample output with the current CVS of gcc is:
> size of a = 1 (should be 0)
> size of b = 8 (should be 8)
> size of c = 16 (should be 12)
> offset of c.z = 12 (should be 8)
I have no idea whether it's correct, but i can tell you *why* it happens.
-fclass-hierarchy-dump shows:

Class a
   size=1 align=1
a (0x3015d500) 0 empty

Class b
   size=8 align=4
b (0x3015d7c0) 0
  a (0x3015d800) 0 empty

Class c
   size=16 align=4
c (0x3015db00) 0
  a (0x3015db40) 0 empty


If you force it to pack them (__attribute__ packed or whatever), you'll
get:
size of a = 1 (should be 0)
size of b = 8 (should be 8)
size of c = 13 (should be 12)
offset of c.z = 9 (should be 8)

And the class-hierarchy-dump will show:
Class a
   size=1 align=1
a (0x3015d500) 0 empty

Class b
   size=8 align=1
b (0x3015d800) 0
  a (0x3015d840) 0 empty

Class c
   size=13 align=1
c (0x3015db40) 0
  a (0x3015db80) 0 empty


I dunno whether the empty base class should have size=0 align=0, but if
it did, this should cause the others to do what you expect.

>
> If this is correct, I would appreciate it if somebody could explain it.
>
> Thanks,
> 	-Sam Lantinga, Software Engineer, Blizzard Entertainment
>

^ permalink raw reply	[flat|nested] 4+ messages in thread

* C++ bug in structure packing and inheritance
@ 2001-12-15 15:07 Sam Lantinga
  2001-12-15 16:09 ` Daniel Berlin
  0 siblings, 1 reply; 4+ messages in thread
From: Sam Lantinga @ 2001-12-15 15:07 UTC (permalink / raw)
  To: gcc; +Cc: slouken

There seems to be a bug in structure packing in that if you have
two classes or structures that both inherit from a class with no
data members, then they will be the wrong size.

A simple example follows:

#include <stddef.h>
#include <stdio.h>

struct a {
};

struct b : public a {
	float x;
	float y;
};

struct c : public a {
	b data;
	float z;
};

main()
{
	printf("size of a = %d (should be 0)\n", sizeof(a));
	printf("size of b = %d (should be 8)\n", sizeof(b));
	printf("size of c = %d (should be 12)\n", sizeof(c));
	printf("offset of c.z = %d (should be 8)\n", offsetof(c,z));
}

Sample output with the current CVS of gcc is:
size of a = 1 (should be 0)
size of b = 8 (should be 8)
size of c = 16 (should be 12)
offset of c.z = 12 (should be 8)

If this is correct, I would appreciate it if somebody could explain it.

Thanks,
	-Sam Lantinga, Software Engineer, Blizzard Entertainment

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2001-12-16  7:42 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2001-12-15 23:40 C++ bug in structure packing and inheritance Sam Lantinga
2001-12-15 23:57 ` Alexandre Oliva
  -- strict thread matches above, loose matches on Subject: below --
2001-12-15 15:07 Sam Lantinga
2001-12-15 16:09 ` Daniel Berlin

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).