🎉 Celebrating 25 Years of GameDev.net! 🎉

Not many can claim 25 years on the Internet! Join us in celebrating this milestone. Learn more about our history, and thank you for being a part of our community!

sizeof structures and vc++

Started by
8 comments, last by derwiath 24 years, 7 months ago
I just tested a few scenarios in VC6 and I'm getting the numbers that you are expecting. It is possible that you have something turned on or off that causes the compiler to pad your structs.

-fel

~ The opinions stated by this individual are the opinions of this individual and not the opinions of her company, any organization she might be part of, her parrot, or anyone else. ~
Advertisement
I believe this has to do with the structure padding that vc does(this is adjustable) VC generally tries to align structures on 4 byte(32 bit) intervals for greater efficiency when processing...

David Wrighton

Ahh, so thats the reason.
Was kind of worried there for a while, thought i had missed something essential in the language...
Thanks a bounch.

/Derwiath

------------------

------------------------------- Derwiath -
Actually it just occurred to me... If you go to Project->Settings, click the "C/C++" tab, and put the "Category" combo box on "Code Generation", you will get a "Struct member alignment" combo box that you can choose alignment in. For your math to work you need to set it to 1 byte.

It's been a while since I played with that setting.

-fel

~ The opinions stated by this individual are the opinions of this individual and not the opinions of her company, any organization she might be part of, her parrot, or anyone else. ~
For the record, it's probably a good idea to let your compiler pad structs for you. It does it because it's more efficient, so unless memory is a major concern, you're going to be better off leaving it alone.
The one time you DON'T want padding however is for reading in entire structures from a file. To allow the compiler to pad the rest of your program for speed and just certain areas for accurateness, use the following (VC only):

#pragma pack(push, original)
#pragma pack(1)

// Put structure here

#pragma pack(pop, original)

- Splat

Another alternative to all of this is data alignment.
What this means is this:
The compiler is going to add padding to every variable that is not a multiple of four. So you need to make sure that this does not happen!

An example.
struct test
{
char bob;
char bob2;
int itest;
int ib;
short it;
};
sizeof (test) = 16 bytes. 4 bytes padding.

New version:
struct test
{
// char bob;
// char bob2;
int itest;
int ib;
short it;
char bob;
char bob2;
};
sizeof (test) = 12 bytes. no bytes padding!

You have made a boundary ok structure.

Some times it is not possible to make a strucuture completely boundary aligned.
This is where you define (future flags of type char) for future expansion, instead of padding.
E.g.
struct test
{
int itest;
int ib;
short it;
}; (2 bytes padding at end.)

becomes
struct test
{
int itest;
int ib;
short it;
char flag1; // future flag
char flag2; // future flag
}; (0 bytes padding at end.)


I'm guessing Microsoft does this all the time.

On a side note, be careful of #pragma pack and where you put it in you're code.
It can cause very hard to spot errors.
What's the rule?
Never put more code between the starting pack's and ending pack's than is needed!

I ran into this issue about a year ago, when I had a binary file of a 30 byte data chunks, and I made a 30 byte structure to hold it, but VC++ (and Borland) made the struct 32 bytes. This is common to all modern platforms, for efficiency, but there are reasons you SHOULD NOT change this behavior. Some platforms (MIPS, ALPHA) CAN NOT accept 32 bit data that is not on a 4 byte boundry, and 64 bit data must be on an 8 byte boundry. In general the rule is: all data should always be stored on a boundry devisible by it's size (I mean 1,2,4, and 8 byte data, since larger data only gets into the CPU in smaller chunks). So, I think the BEST solution was outlined in the top half of Gorky's post. MANUALY pad your own structures by the rule above, so that YOU have the control, and your struct will compile to the same size on all platforms (so you wont get any data compatibility issues).

By the way, the compiler option to control pading if you have the need (in VC 6.0) is /Zp# - where # is either 1,2,4, or 8. And here is a quote from the MSDN library:

"The Struct Member Alignment (/Zpn) option controls how the members of a structure are packed into memory and specifies the same packing for all structures in a module. When you specify this option, each structure member after the first is stored on either the size of the member type or n-byte boundaries (where n is 1, 2, 4, 8, or 16), whichever is smaller.

You should not use this option unless you have specific alignment requirements."

Hello.
This isnt realy game related but I thought I'd bring it up here anyway.
This is the thing, I created a struct as the one below:

struct Test{
int iTest;
char cTest;
};

And i did a sizeof(Test) and it returned 8!!
this is kind of strange since an int is 4 bytes and a char is 1 byte....4 + 1 = 5 if i dont remember wrong.
I tried to add one char to the struct and still got the size 8. Not until i had added 5 char's the result changed to 12.
If i removed the int from the struct and had only one char i got the correct size 1, so it seems that this phenomenon only appears when i combine int and char's.The same strangeness
also appears if i use a short and an int in the struct.
Is this really the way it is suposed to be??
I have tried my little experiment on both vc++5 and 6.
Has anyone else had this "problem"??


------------------

------------------------------- Derwiath -
To reinforce both what has been said above both by others and myself: Do NOT change the Microsoft global alignment settings. This is bad practice, slows down code (sometimes VERY much), and itsn't always supported (altohugh mostly is).

Instead, use whatever compiler-specific method of changing the packing settings right before and after a specific structure.

Or pad yourself so that you control that padding process - although in space-critical situations this is bad as well, because with a huge number of entries those extra bytes start to add up.

- Splat

This topic is closed to new replies.

Advertisement