Link to home
Start Free TrialLog in
Avatar of nil_dib
nil_dib

asked on

strange sizeof() behaviour!

Can someone produce this ?

typedef struct stSOMETHING
{
    unsigned long  l;
    unsigned short s;

} SOMETHING, *PSOMETHING;

int nSize = sizeof(SOMETHING);
// nSize = 8 ??!!

I'm on VC5.0 SP 3
NT4.0 SP 4
ASKER CERTIFIED SOLUTION
Avatar of nietod
nietod

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of nietod
nietod

By default when the compiler defines a structure, it alligns the multi-byte values so that their offset within the structure is divisible by 4.  This way when objects of the structure are created, their members will start on doubleword boundaries (addresses that are evenly divisible by 4).  (The assumes that the structure is positioned so it starts on a doubleword boundary, which is something that the compiler will also do at every opportunity.)  This allows the data in the members to be accessed more quickly.
Avatar of nil_dib

ASKER

but:

typedef struct stSOMETHING
{
    unsigned short s;
} SOMETHING, *PSOMETHING;

int nSize = sizeof(SOMETHING);
// nSize = 2 !
 

Avatar of nil_dib

ASKER

>> the default allignment for VC
this is VC specific ?
You can control this process using the "pack" #pragma.  For example, you could do

#pragma pack (push,1)
typedef struct stSOMETHING
{
   unsigned long  l;
   unsigned short s;
} SOMETHING, *PSOMETHING;
#pragma pack(pop)

this makes the packing align to 1 but boundaries (no allignhment) while the structure is declared, then returns the alignment to it previous value.

Not also that you don't have to define structures using a typedef like that.  C++ considers structures to be complete types.  
>> this is VC specific ?
yes and no.

The C++ standard allows a compilers to do this.  Some do and some don't.  This depends on a) how concerned they are for speed verses size (it makes structures larger, but faster to use) and b) if the hardware the compiler is designed for can access aligned data faster than unaligned data.  (This is true of most modern CPUs, but older, simpler, CPUs didn't access aligned data any faster, so it would be a waste for them.)  Thus some compilers do so and others don't.  VC allows you to control it with the pragma, however, most other compilers won't do this, or may do so using a different syntax or approach (Like command-line options.)
Note 80286 computers and later (like pentiums) all access data faster when alligned to doubleword boundaries, and even faster when alligned to paragraph (16 byte) boundaries). In addition all the win32 windows structures are defined assuming doubleword alignment, so any win32 compiler you find will do this.