Why Does a Long Int Take 12 Bytes on Some Machines?

cmemorypointers

I noticed something strange after compiling this code on my machine:

#include <stdio.h>

int main()
{
    printf("Hello, World!\n");

    int a,b,c,d;

    int e,f,g;

    long int h;

    printf("The addresses are:\n %0x \n %0x \n %0x \n %0x \n %0x \n %0x \n %0x \n %0x",
        &a,&b,&c,&d,&e,&f,&g,&h);

    return 0;
}

The result is the following. Notice that between every int address there is a 4-byte difference. However between the last int and the long int there is a 12-byte difference:

 Hello, World!
 The addresses are:

 da54dcac 
 da54dca8 
 da54dca4 
 da54dca0 
 da54dc9c 
 da54dc98 
 da54dc94 
 da54dc88

Best Answer

It didn't take 12 bytes, it only took 8. However, the default alignment for an 8 byte long int on this platform is 8 bytes. As such, the compiler needed to move the long int to an address that's divisible by 8. The "obvious" address, da54dc8c, isn't divisible by 8 hence the 12 byte gap.

You should be able to test this. If you add another int prior to the long, so there are 8 of them, you should find that the long int will be aligned ok without a move. Now it'll be only 8 bytes from the previous address.

It's probably worth pointing out that, although this test should work, you shouldn't rely on the variables being organised this way. A C compiler is allowed to do all sorts of funky stuff to try to make your program run quickly including re-ordering variables (with some caveats).