tags:

views:

711

answers:

6

Are pointers on a 64-bit system still 4 byte aligned (similar to a double on a 32 bit system)? Or are they note 8 byte aligned?

For example, on a 64-bit system how big is the following data structure:

struct a {
    void* ptr;
    char myChar;
}

Would the pointer by 8 byte aligned, causing 7 bytes of padding for the character (total = 8 + 8 = 16)? Or would the pointer be 4 byte aligned (4 bytes + 4 bytes) causing 3 bytes of padding (total = 4 + 4 + 4 = 12)?

Thanks, Ryan

+5  A: 

I don't think you can rely on any hard-and-fast rules. I think it's a function of the compiler you use and the compilation options you choose.

Your best bet is to write a program that tests this and spits out a header file that codifies the alignment rules as #defines. You might also be able to just calculate what you're interested in right in the macros, too.

A: 

Generally on a 64-bit system:

struct a {
    void* ptr;      // size is 8 bytes, alignment is 8
    char myChar;    // size is 1 byte,  alignment is 1
                    // padding of 7 bytes so array elements will be properly aligned
}

For a total size of 16 bytes.

But this is all implementation defined - I'm just giving an example that likely to be true for many (most?) 64-bit systems.

Michael Burr
+1  A: 

Data alignment and packing are implementation specific, and can be usually changed from compiler settings (or even with pragmas).

However assuming you're using default settings, on most (if not all) compilers the structure should end up being 16 bytes total. The reason is because computers reads a data chunk with size of its native word size (which is 8 bytes in 64-bit system). If it were to pad it to 4 byte offsets, the next structure would not be properly padded to 64-bit boundary. For example in case of a arr[2], the second element of the array would start at 12-byte offset, which isn't at the native byte boundary of the machine.

reko_t
A: 

You would need to consult the documentation for the particular ABI you are interested in. For example, here is the System V ABI x86-64 architeture supplement - you can see on page 12 that pointers on this ABI are 8-byte aligned (so yes, the structure you show would be padded out to 16 bytes).

caf
+1  A: 

The language standard makes no statements about padding. The alignment rules are platform-specific (i.e., you have to align differently on e.g. a PowerPC CPU than on a x86_64 CPU), and they are implementation-defined, meaning your compiler can do whatever works (and might change that behaviour with different command-line options or after a version update).

I strongly believe that any recommendation along the lines of "this is usually this or that" is misleading, and possibly dangerous.

  1. You could write a test program that executes a couple of sizeof() and/or offsetof()statements and writes a header for you containing some #defines stating the paddings used.

  2. You can use autoconf to do that for you.

  3. In the very least, you should add assert( sizeof( ... ) ) statements at the beginning of your main() function so you get informed when your assumptions are wrong.

DevSolar
+3  A: 

Blog post: Change of type alignment and the consequences

Types’ sizes and alignment

Andrey Karpov
you can align `long long` and `double` variables along 8 byte boundaries on 32-bit x86 via passing `-malign-double` to gcc
Christoph
It is **WRONG** to give tables like this. Alignment is **platform-specific** and **implementation-defined**. Bottom line, your table **might** be correct, just as well as a program relying on these values **might** work correctly.
DevSolar