实施结构大小对齐

时间:2015-02-01 20:17:26

标签: c memory-alignment c11

有没有办法强制结构的大小是任何类型所需最大对齐的倍数?以下是两种不同的尝试:

#include <stdio.h>
#include <stddef.h>
#include <stdalign.h>

typedef struct {
    char c;
} Block1;

typedef struct {
    char c;
    max_align_t data[];
} Block2;

typedef struct {
    char c;
    _Alignas(sizeof(max_align_t)) max_align_t data[];
} Block3;

int
main() {
    printf("sizeof(max_align_t): %zu\n", sizeof(max_align_t));
    printf("sizeof(Block1): %zu\n", sizeof(Block1));
    printf("sizeof(Block2): %zu\n", sizeof(Block2));
    printf("sizeof(Block3): %zu\n", sizeof(Block3));
}

在64位计算机上使用gcc 4.9.2我得到了这个,所以Block3似乎有效。有趣的是,Block2不起作用,但我可以猜到为什么:

sizeof(max_align_t): 32
sizeof(Block1): 1
sizeof(Block2): 16
sizeof(Block3): 32

只是想知道Block3是否有效(按照C11标准),以及是否有更好的方法。

ADDENDUM:显然,我误解了max_align_t的含义。我认为sizeof(max_align_t)给出了任何标量类型所需的最大对齐,但显然它是_Alignof(max_align_t)给出的。所以Block2确实有效。

1 个答案:

答案 0 :(得分:2)

  

有没有办法强制结构的大小是所需最大对齐的倍数?

好吧,如果你的意思是它的元素的最大对齐,那总是很简单。你完成了。

如果您的意思是某些基本对齐

  1. 在成员上使用_Alignas(type)(您不能以这种方式意外降低对齐要求)。
  2. 使用与上面对齐的类型的成员。您的第二个示例使用灵活阵列成员。
  3. max_align_t具有最大的基本对齐。

    如果您的意思是某些扩展对齐_Alignas(power_of_two)是您的朋友(必须诊断不支持的对齐),但不能保证支持过度对齐的类型。
    也没有办法查询最大支持的扩展对齐。

      

    6.2.8对象的对齐

         

    1完整对象类型具有对齐要求,这些要求对可以分配该类型对象的地址施加限制。对齐是一个   实现定义的整数值,表示之间的字节数   可以分配给定对象的连续地址。对象类型对该类型的每个对象强加对齐要求:可以使用_Alignas关键字请求更严格的对齐。
      2 基本对齐由小于或等于所有上下文中实现所支持的最大对齐的对齐表示,等于_Alignof (max_align_t)
      3 扩展对齐由大于_Alignof (max_align_t)的对齐表示。它是实现定义的,是否支持任何扩展对齐以及支持它们的上下文。具有扩展对齐要求的类型是过度对齐类型.57)
      4对齐表示为size_t类型的值。有效对齐仅包括基本类型的_Alignof表达式返回的值,以及可能为空的其他实现定义值集。每个有效的对齐值应为2的非负整数幂   5对齐具有从更强更严格对齐的顺序。更严格的对齐具有更大的对齐值。满足对齐要求的地址也满足任何较弱的有效对齐要求   6可以使用_Alignof表达式查询完整类型的对齐要求。类型charsigned charunsigned char应具有最弱的对齐要求。
      7比较比对是有意义的,并提供了明显的结果:

         
        
    • 当数值相等时,两个对齐相等。
    •   
    • 当数值不相等时,两个对齐方式不同。
    •   
    • 当对齐比另一个大时,它表示更严格的对齐。
    •