#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 :-)