【问题标题】:Relationship between alignment of class fields and alignment of object instances in C++?C++中类字段对齐和对象实例对齐之间的关系?
【发布时间】:2021-07-30 08:27:58
【问题描述】:

给定以下 C++ 类:

class X {
public:
    uint8_t a;
    uint32_t b[256] __attribute__((aligned(32)));
};

X 的实例可能是字对齐时,编译器如何确保b 的存储是32 字节对齐的? aligned 属性是否仅指定相对于对象实例起始地址的对齐方式?如果是这样,使b 32 字节相对于地址空间对齐的正确方法是什么?我应该使用class alignof(32) X {...} 简单地指定对象实例对齐方式吗?

【问题讨论】:

    标签: c++ class oop memory-management alignment


    【解决方案1】:

    标准规定如下:

    [basic.align/2]

    基本对齐由小于或等于所有上下文中实现支持的最大对齐的对齐表示,它等于 alignof(std​::​max_align_t) ([support.types])。当一个类型用作完整对象的类型和用作子对象的类型时,类型所需的对齐方式可能会有所不同。 [例1:

    struct B { long double d; };
    struct D : virtual B { char c; };
    

    当 D 是一个完整对象的类型时,它会有一个 B 类型的子对象,因此对于 long double 必须适当对齐。如果 D 显示为另一个也将 B 作为虚拟基类的对象的子对象,则 B 子对象可能是不同子对象的一部分,从而降低了 D 子对象的对齐要求。 —结束示例]

    还有[dcl.align/5]

    声明中所有对齐说明符的组合效果所指定的对齐方式不应低于如果与该实体相关的所有对齐说明符都被省略的情况下被声明的实体所需的对齐方式。

    [Example 1:
    struct alignas(8) S {};
    struct alignas(1) U {
     S s;
    };  // error: U specifies an alignment that is less strict than if the alignas(1) >were omitted.
    — end example]
    

    因此,从上面的部分(尤其是示例的解释)可以假设对象的对齐方式在其成员中被解析为最严格的。

    class X {
    public:
        uint8_t a;
        alignas(32) uint32_t b[256];
    };
    
    int main() {
        X x1;
        // alignas(16) X x; // Clang error: requested alignment is less than minimum alignment of 32 for type 'X'    
        alignas(64) X x2; // OK 
        alignof(X); // 32
        alignof(x1); //32
        alignof(x2); //64
        alignof(x2.b); //32
        return 0;
    }  
    

    【讨论】:

    • 啊,我不知道可以做到alignas(64) X x2。谢谢!我很欣赏对对齐严格性的澄清。看起来类的默认对齐方式将确保所有字段的对齐方式都将得到遵守。
    猜你喜欢
    • 2011-02-18
    • 2019-11-20
    • 2015-07-18
    • 1970-01-01
    • 1970-01-01
    • 2021-12-19
    • 1970-01-01
    • 2011-11-28
    • 1970-01-01
    相关资源
    最近更新 更多