Question

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)

Was it helpful?

Solution

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).

OTHER TIPS

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.

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.

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 )

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.

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.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top