tags:

views:

302

answers:

6

For example, if I declare a long variable, can I assume it will always be aligned on a "sizeof(long)" boundary? Microsoft Visual C++ online help says so, but is it standard behavior?

some more info:

a. It is possible to explicitely create a misaligned integer (*bar):

char foo[5]

int * bar = (int *)(&foo[1]);

b. Apparently, #pragma pack() only affects structures, classes, and unions.

c. MSVC documentation states that POD types are aligned to their respective sizes (but is it always or by default, and is it standard behavior, I don't know)

A: 

Yes, all types are always aligned to at least their alignment requirements.

How could it be otherwise?

But note that the sizeof() a type is not the same as it's alignment.

You can use the following macro to determine the alignment requirements of a type:

#define ALIGNMENT_OF( t ) offsetof( struct { char x; t test; }, test )
Michael Burr
However, in the Intel x86 family, the alignment "requirement" is merely an a byte address.
James Curran
+3  A: 

By default, yes. However, it can be changed via the pack() #pragma.

I don't believe the C++ Standard make any requirement in this regard, and leaves it up to the implementation.

James Curran
Oh yeah, I forgot about packing options/pragmas.
Michael Burr
It can be set as well with the project/compiler options.
Kris Kumler
A: 

Depends on the compiler, the pragmas and the optimisation level. With modern compilers you can also choose time or space optimisation, which could change the alignment of types as well.

workmad3
A: 

Generally it will be because reading/writing to it is faster that way. But almost every compiler has a switch to turn this off. In gcc its -malign-???. With aggregates they are generally aligned and sized based on the alignment requirements of each element within.

Greg Rogers
+8  A: 

As others have mentioned, this isn't part of the standard and is left up to the compiler to implement as it sees fit for the processor in question. For example, VC could easily implement different alignment requirements for an ARM processor than it does for x86 processors.

Microsoft VC implements what is basically called natural alignment up to the size specified by the #pragma pack directive or the /Zp command line option. This means that, for example, any POD type with a size smaller or equal to 8 bytes will be aligned based on its size. Anything larger will be aligned on an 8 byte boundary.

If it is important that you control alignment for different processors and different compilers, then you can use a packing size of 1 and pad your structures.

#pragma pack(push)
#pragma pack(1)    
struct Example
{
   short data1;     // offset 0
   short padding1;  // offset 2
   long data2;      // offset 4
};
#pragma pack(pop)

In this code, the padding1 variable exists only to make sure that data2 is naturally aligned.

Answer to a:

Yes, that can easily cause misaligned data. On an x86 processor, this doesn't really hurt much at all. On other processors, this can result in a crash or a very slow execution. For example, the Alpha processor would throw a processor exception which would be caught by the OS. The OS would then inspect the instruction and then do the work needed to handle the misaligned data. Then execution continues. The __unaligned keyword can be used in VC to mark unaligned access for non-x86 programs (i.e. for CE).

Torlack
+1  A: 

C and C++ don't mandate any kind of alignment. But natural alignment is strongly preferred by x86 and is required by most other CPU architectures, and compilers generally do their utmost to keep CPUs happy. So in practice you won't see a compiler generate misaligned data unless you really twist it's arm.