简体   繁体   中英

C 64-bit Pointer Alignment

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

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 #define s. You might also be able to just calculate what you're interested in right in the macros, too.

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.

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.

The language standard makes no statements about padding. The alignment rules are platform-specific (ie, you have to align differently on eg 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 #define s 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.

您需要查阅您感兴趣的特定ABI的文档。例如,这是System V ABI x86-64 architeture补充 - 您可以在第12页看到此ABI上的指针是8字节对齐的(所以是的,您显示的结构将填充到16个字节)。

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM