强制结构大小对齐
Enforce struct size alignment
有没有办法强制结构的大小为任何类型所需的最大对齐方式的倍数?这里有两种不同的尝试:
#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 标准),以及是否有更好的方法。
附录:显然,我误解了 max_align_t
的意思。我认为 sizeof(max_align_t)
给出了任何标量类型所需的最大对齐,但显然是 _Alignof(max_align_t)
给出了这个。所以 Block2
实际上有效。
Is there a way to force the size of a struct to be a multiple of the maximum required alignment?
好吧,如果您指的是其元素的最大对齐方式,那么情况总是如此。你完成了。
如果相反,你的意思是一些基本对齐,
- 对成员使用
_Alignas(type)
(您不会以这种方式不小心降低对齐要求)。
- 使用像上面那样对齐的类型的成员。你的第二个例子使用了一个灵活的数组成员这样做。
max_align_t
具有最大的基本对齐。
如果您的意思是 扩展对齐方式 ,_Alignas(power_of_two)
是您的朋友(必须诊断不支持的对齐方式),但不能保证支持过度对齐类型完全没有。
也没有任何方法可以查询最大支持的扩展对齐方式。
6.2.8 Alignment of objects
1 Complete object types have alignment requirements which place restrictions on the addresses at which objects of that type may be allocated. An alignment is an
implementation-defined integer value representing the number of bytes between
successive addresses at which a given object can be allocated. An object type imposes an alignment requirement on every object of that type: stricter alignment can be requested using the _Alignas
keyword.
2 A fundamental alignment is represented by an alignment less than or equal to the greatest alignment supported by the implementation in all contexts, which is equal to _Alignof (max_align_t)
.
3 An extended alignment is represented by an alignment greater than _Alignof (max_align_t)
. It is implementation-defined whether any extended alignments are supported and the contexts in which they are supported. A type having an extended alignment requirement is an over-aligned type.57)
4 Alignments are represented as values of the type size_t
. Valid alignments include only those values returned by an _Alignof
expression for fundamental types, plus an additional implementation-defined set of values, which may be empty. Every valid alignment value shall be a nonnegative integral power of two.
5 Alignments have an order from weaker to stronger or stricter alignments. Stricter alignments have larger alignment values. An address that satisfies an alignment requirement also satisfies any weaker valid alignment requirement.
6 The alignment requirement of a complete type can be queried using an _Alignof
expression. The types char
, signed char
, and unsigned char
shall have the weakest alignment requirement.
7 Comparing alignments is meaningful and provides the obvious results:
- Two alignments are equal when their numeric values are equal.
- Two alignments are different when their numeric values are not equal.
- When an alignment is larger than another it represents a stricter alignment.
有没有办法强制结构的大小为任何类型所需的最大对齐方式的倍数?这里有两种不同的尝试:
#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 标准),以及是否有更好的方法。
附录:显然,我误解了 max_align_t
的意思。我认为 sizeof(max_align_t)
给出了任何标量类型所需的最大对齐,但显然是 _Alignof(max_align_t)
给出了这个。所以 Block2
实际上有效。
Is there a way to force the size of a struct to be a multiple of the maximum required alignment?
好吧,如果您指的是其元素的最大对齐方式,那么情况总是如此。你完成了。
如果相反,你的意思是一些基本对齐,
- 对成员使用
_Alignas(type)
(您不会以这种方式不小心降低对齐要求)。 - 使用像上面那样对齐的类型的成员。你的第二个例子使用了一个灵活的数组成员这样做。
max_align_t
具有最大的基本对齐。
如果您的意思是 扩展对齐方式 ,_Alignas(power_of_two)
是您的朋友(必须诊断不支持的对齐方式),但不能保证支持过度对齐类型完全没有。
也没有任何方法可以查询最大支持的扩展对齐方式。
6.2.8 Alignment of objects
1 Complete object types have alignment requirements which place restrictions on the addresses at which objects of that type may be allocated. An alignment is an implementation-defined integer value representing the number of bytes between successive addresses at which a given object can be allocated. An object type imposes an alignment requirement on every object of that type: stricter alignment can be requested using the
_Alignas
keyword.
2 A fundamental alignment is represented by an alignment less than or equal to the greatest alignment supported by the implementation in all contexts, which is equal to_Alignof (max_align_t)
.
3 An extended alignment is represented by an alignment greater than_Alignof (max_align_t)
. It is implementation-defined whether any extended alignments are supported and the contexts in which they are supported. A type having an extended alignment requirement is an over-aligned type.57)
4 Alignments are represented as values of the typesize_t
. Valid alignments include only those values returned by an_Alignof
expression for fundamental types, plus an additional implementation-defined set of values, which may be empty. Every valid alignment value shall be a nonnegative integral power of two.
5 Alignments have an order from weaker to stronger or stricter alignments. Stricter alignments have larger alignment values. An address that satisfies an alignment requirement also satisfies any weaker valid alignment requirement.
6 The alignment requirement of a complete type can be queried using an_Alignof
expression. The typeschar
,signed char
, andunsigned char
shall have the weakest alignment requirement.
7 Comparing alignments is meaningful and provides the obvious results:
- Two alignments are equal when their numeric values are equal.
- Two alignments are different when their numeric values are not equal.
- When an alignment is larger than another it represents a stricter alignment.