alignof

alignof(type),用于获取类型的对齐字节数;返回size_t类型;alignof只能用于类型。

#include <iostream>

using namespace std;

struct DemoStruct2 {
    short s1;                  // 2B
    short s2;                  // 2B
                               // Padding 4B(因为sdb1结构体是8字节对齐的, 所以sdb1.sc1相对于首地址的偏移必须是8的倍数,所以在sdb1.sc1之前填充4B)
    struct SubDemoStruct1 {
        char sc1;              // 1B
                               // Padding 7B
        long long int slli1;   // 8B
    } sdb1;
    struct SubDemoStruct2 {
        char sc1;              // 1B
    } sdb2;
                               // Padding 3B(因为sdb3结构体是4字节对齐的, 所以sdb3.si1相对于首地址的偏移必须是4的倍数,所以在sdb3.si1之前填充3B)
    struct SubDemoStruct3 {
        int si1;               // 4B
    } sdb3;
    char c1;                   // 1B
                               // Padding 7B(因为结构体中最大成员的size是8, 所以结构体的总大小必须是8的倍数,所以在结构体最后填充7B)

};

int main()
{
    cout << "alignof(DemoStruct2): " << alignof(DemoStruct2) << endl;
    cout << "alignof(DemoStruct2::SubDemoStruct1): " << alignof(DemoStruct2::SubDemoStruct1) << endl;
    cout << "alignof(DemoStruct2::SubDemoStruct2): " << alignof(DemoStruct2::SubDemoStruct2) << endl;
    cout << "alignof(DemoStruct2::SubDemoStruct3): " << alignof(DemoStruct2::SubDemoStruct3) << endl;
    return 0;
}

输出:

alignof(DemoStruct2): 8
alignof(DemoStruct2::SubDemoStruct1): 8
alignof(DemoStruct2::SubDemoStruct2): 1
alignof(DemoStruct2::SubDemoStruct3): 4

alignas

alignas(number) type,用于改变目标类型的对齐字节数。

1. 修改结构体的字节对齐规则

struct Test {
    char a;
    char b;
    test()
    {
        cout << "sizeof(Test) =" << sizeof(Test) << endl;    // 2
        cout << "alignof(Test) =" << alignof(Test) << endl;  // 1
    }
};

struct alignas(4) Test {
    char a;
    char b;
    test()
    {
        cout << "sizeof(Test) =" << sizeof(Test) << endl;    // 4
        cout << "alignof(Test) =" << alignof(Test) << endl;  // 4
    }
};

2. 修改结构体内部变量的对齐规则

struct Test
{
    char a;
    char b;
    alignas(2) char c;
    void test()
    {
        cout << "sizeof(Test) =" << sizeof(Test) << endl;   // 8
        cout << "alignof(Test) =" << alignof(Test) << endl; // 4

        cout << "offset of a: " << offsetof(Test, a) << endl; // 0
        cout << "offset of b: " << offsetof(Test, b) << endl; // 1
        cout << "offset of c: " << offsetof(Test, c) << endl; // 2
    }
};

注意:

  • alignas设置的是变量的对齐规则,不影响struct内其他同类型的变量
  • alignas不一定生效,alignas会和默认的对齐规则取最大值
  • 如果struct和struct成员变量都设置了alignas,对齐规则取最大值

3. 修改普通变量的对齐规则

    int a;
    auto b = reinterpret_cast<intptr_t>(&a) % 16;
    cout << b << endl;

int默认以4对齐,则a的地址对16取模,可能是0 4 8 12。

alignas(16) int a;
auto b = reinterpret_cast<intptr_t>(&a) % 16;
cout << b << endl;

设置a16字节对齐,则a的地址对16取模,必定是0。