gbadev.org forum archive

This is a read-only mirror of the content originally found on forum.gbadev.org (now offline), salvaged from Wayback machine copies. A new forum can be found here.

C/C++ > struct sizes with C++

#2404 - kyp4 - Mon Feb 03, 2003 4:21 am

I am having a problem with structure sizes. I am using C++ with devkitadv. If I define the following structure:
Code:

struct test
{
    u8 byte;
};

The size of the structure (checked by using sizeof() and by making an array and checking the addresses of consecutive elements) is 4 bytes, rather than only 1 byte, which is the sizeof(u8). I then tried various combinations of element types and it seems as though the sizes of structures are always multiples of 4 bytes.
Previously to doing this on the GBA I tried it in a Win32 console program and, as I expected it to do, a structure's size is merely the sum if its elements. Is there any reason why structures are always multiples of 4 bytes and is there anyway to tell the compiler not to do this?

#2405 - tepples - Mon Feb 03, 2003 4:35 am

kyp4 wrote:
I then tried various combinations of element types and it seems as though the sizes of structures are always multiples of 4 bytes.

That's a reasonable choice to make on a 32-bit architecture.

Quote:
Previously to doing this on the GBA I tried it in a Win32 console program

The size of structures is implementation-defined. MSVC on x86 will compile differently from GCC on x86, which will compile differently from GCC on ARM.

Quote:
Is there any reason why structures are always multiples of 4 bytes and is there anyway to tell the compiler not to do this?

You could try telling the compiler that you want the structure "packed", using attributes. To learn how to specify this behavior, read this page from the GCC manual.
_________________
-- Where is he?
-- Who?
-- You know, the human.
-- I think he moved to Tilwick.

#2417 - Touchstone - Mon Feb 03, 2003 4:03 pm

Instead of using compilerspecific 'pack'-attributes you could take a look at bitfields. The size of your struct will still be padded to four bytes but the members won't have to be 'properly' aligned.
_________________
You can't beat our meat

#2431 - tepples - Mon Feb 03, 2003 9:29 pm

Bitfields won't be aligned the same on different compilers either. That too is implementation-defined behavior. And though I haven't benchmarked bitfields on ARM, they're dog-slow on x86.
_________________
-- Where is he?
-- Who?
-- You know, the human.
-- I think he moved to Tilwick.

#2439 - Vortex - Tue Feb 04, 2003 12:07 am

There is one more thing to be considered: In C++ (unlike C) the structures are *class* types. That means you can include methods in your struct. As a side effect some compilers may include an invisible "this" pointer when working with structs. My experience is the sizeof() operator returns suprizing results used with struct/class argument in C++, but again that depends on the compiler.

Since you are not using any OOP I would suggest to include your struct definition in a separate C file and the include it in the C++ file as "extern C". In that way you can be sure the compiler will apply the good old C rules when allocation space for your structure variables.

#2447 - tepples - Tue Feb 04, 2003 4:24 am

Vortex wrote:
As a side effect some [C++ language] compilers may include an invisible "this" pointer when working with structs.

There's no this pointer stored in a C++ class. The this pointer is a pointer to an object, passed as an implicit argument to each non-static method. What you're thinking of is the hidden field that points to the class's virtual method jump table (vtable). A class or struct with no destructor and no other virtual functions won't have a vtable field.

Quote:
I would suggest to include your struct definition in a separate C file and the include it in the C++ file as "extern C"

As far as I know, extern "C" affects only functions, to make them use C calling conventions: no overloading, no name mangling, and no namespacing. For structs and for everything else other than functions, a compiler ignores extern "C".
_________________
-- Where is he?
-- Who?
-- You know, the human.
-- I think he moved to Tilwick.

#2478 - Vortex - Tue Feb 04, 2003 5:19 pm

Quote:

There's no this pointer stored in a C++ class. The this pointer is a pointer to an object, passed as an implicit argument to each non-static method. What you're thinking of is the hidden field that points to the class's virtual method jump table (vtable). A class or struct with no destructor and no other virtual functions won't have a vtable field.


You are correct, except for one thing: if you don't specify a destructor the compiler will supply a default one for you. I tried this using BC++ a long time ago and the overhead was there regardless of the destructor/virtual methods. Since the C++ compilers are much smarter now I think your statement can be considered 100% correct.

Quote:
I would suggest to include your struct definition in a separate C file and the include it in the C++ file as "extern C"
As far as I know, extern "C" affects only functions, to make them use C calling conventions: no overloading, no name mangling, and no namespacing. For structs and for everything else other than functions, a compiler ignores extern "C".


My bad. That only shows how rusty my C++ knoledge is :-)