c++ - 编译器会偷偷增加结构的对齐吗?

标签 c++ c struct memory-alignment

我有一个8字节对齐的struct,但是当我连续定义一些这种类型的变量而不是在数组中时,它似乎是16字节对齐。我的问题是,编译器是否出于某种目的增加了对齐?

我的测试代码是:

#include <stdio.h>
#include <stdint.h>
struct a{
    long l[3];
};

struct a a1;
struct a a2;
struct a a3;

int main(){
    printf("%lx\n", (uintptr_t)&a1);
    printf("%lx\n", (uintptr_t)&a2);
    printf("%lx\n", (uintptr_t)&a3);
    return 0;
}

输出是:

601030
601050
601070

最佳答案

在 64 位 Unix 机器(运行 macOS Sierra 10.12.6,使用 GCC 7.1.0 的 Mac)上,此代码:

#include <stdio.h>
#include <inttypes.h>
struct a
{
    long l[3];
};

struct a a1;
struct a a2;
struct a a3;
struct a a4[4];

int main(void)
{
    printf("sizeof(struct a) = %zu\n", sizeof(struct a));
    printf("a1 = 0x%.16" PRIXPTR "\n", (uintptr_t)(void *)&a1);
    printf("a2 = 0x%.16" PRIXPTR "\n", (uintptr_t)(void *)&a2);
    printf("a3 = 0x%.16" PRIXPTR "\n", (uintptr_t)(void *)&a3);
    for (int i = 0; i < 4; i++)
        printf("a4[%d] = 0x%.16" PRIXPTR "\n", i, (uintptr_t)(void *)&a4[i]);
    return 0;
}

产生这个结果:

sizeof(struct a) = 24
a1 = 0x0000000106776020
a2 = 0x0000000106776040
a3 = 0x0000000106776060
a4[0] = 0x0000000106776080
a4[1] = 0x0000000106776098
a4[2] = 0x00000001067760B0
a4[3] = 0x00000001067760C8

请注意,三个独立结构按 32 字节边界布置,但数组中的结构按 24 字节边界布置,正如结构大小(24 字节)所预期的那样。

相比之下(与此答案的早期版本相反),使用 Clang(Apple LLVM 版本 8.1.0 (clang-802.0.42))编译会产生结果:

sizeof(struct a) = 24
a1 = 0x0000000102ACE020
a2 = 0x0000000102ACE038
a3 = 0x0000000102ACE050
a4[0] = 0x0000000102ACE070
a4[1] = 0x0000000102ACE088
a4[2] = 0x0000000102ACE0A0
a4[3] = 0x0000000102ACE0B8

请注意,单个结构现在布置在 24 字节边界上(或者至少相隔 24 字节,而不是 GCC 中的 32 字节)。

我没有解释为什么 GCC 添加了空间,但是 编译器完全可以自由地这样做。 两个编译器都是正确的——结果完全不同。

关于c++ - 编译器会偷偷增加结构的对齐吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45396395/

相关文章:

c++ - 退出后代码崩溃?

复制指向函数中结构体的指针(链表)

c++ - 你如何在 C++ 中读入一个 3 字节大小的值作为整数?

c++ - 在键盘输入期间测试事件标志

c++ - 使用 double 的程序的意外行为

c - 字符数组中包含空字符和排除空字符有什么区别?

c - C 中的随机整数,rand()%N 与整数运算相比有多糟糕?它的缺陷是什么?

C 在我编写的程序中正确使用 malloc 和 free

ruby - 从结构创建类的不同方法之间有什么区别?

C++ 在一组字符串对中搜索一个字符串