如何检查对齐是否在 C 中有效?
How to check if an alignment is valid in C?
我正在编写的代码需要完全符合标准。该标准不承诺任何比 max_align_t
更强的对齐选项。我想尝试与缓存行对齐,但我知道如果实现不支持这种强度的对齐,那将是未定义的行为。
有什么办法解决这个问题吗?有什么方法可以在预处理时检查哪些扩展对齐可用?或者,如果对齐不可用,是否有任何方法可以请求对齐,只是没有得到它,而不是有未定义的行为?
aligned_alloc
适用于分配的内存。不过,我对静态存储的内存也很感兴趣。
编辑:
为了说明我的问题,以下是我遇到问题的 C11 标准中的语句:
6.2.8
- 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.
所以任何给定的 2 次幂都不一定是有效对齐,我不能指望 64 小于或等于 max_align_t
,因此 64 可能不是有效对齐。如果它不是有效对齐,这是我的未定义行为问题:
6.7.5 Alignment specifier
- The constant expression shall be an integer constant expression. It shall evaluate to a valid fundamental alignment, or to a valid extended alignment supported by the implementation in the context in which it appears, or to zero.
我认为,您需要查看函数 valloc() 或 memalign()。
另外,非常有用的调用:
int pagesize = sysconf(_SC_PAGESIZE);
如果您需要将缓冲区与页面大小对齐,您可以调用:
char *buf = ...; // Buffer to unaligned memory
buf -= (uinsigned)buf & (pagesize - 1); // align to low border
buf += pagesize; // align to high border
您的编译器自己选择的对齐方式不应比 max_align_t
更宽,但仅此而已。没有禁止要求更广泛的结盟。
因此,要确保 struct
的特定字段位于您希望的边界上,您只需使用 _Alignas
。只要您要求的值是 2 的幂,并且您的编译器允许特定的对齐方式,所有这些都是明确定义的。如果不是,你的编译器必须抱怨。
这正是在 C11 中添加 _Alignas
的原因之一。
我正在编写的代码需要完全符合标准。该标准不承诺任何比 max_align_t
更强的对齐选项。我想尝试与缓存行对齐,但我知道如果实现不支持这种强度的对齐,那将是未定义的行为。
有什么办法解决这个问题吗?有什么方法可以在预处理时检查哪些扩展对齐可用?或者,如果对齐不可用,是否有任何方法可以请求对齐,只是没有得到它,而不是有未定义的行为?
aligned_alloc
适用于分配的内存。不过,我对静态存储的内存也很感兴趣。
编辑: 为了说明我的问题,以下是我遇到问题的 C11 标准中的语句:
6.2.8
- 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.
所以任何给定的 2 次幂都不一定是有效对齐,我不能指望 64 小于或等于 max_align_t
,因此 64 可能不是有效对齐。如果它不是有效对齐,这是我的未定义行为问题:
6.7.5 Alignment specifier
- The constant expression shall be an integer constant expression. It shall evaluate to a valid fundamental alignment, or to a valid extended alignment supported by the implementation in the context in which it appears, or to zero.
我认为,您需要查看函数 valloc() 或 memalign()。 另外,非常有用的调用:
int pagesize = sysconf(_SC_PAGESIZE);
如果您需要将缓冲区与页面大小对齐,您可以调用:
char *buf = ...; // Buffer to unaligned memory
buf -= (uinsigned)buf & (pagesize - 1); // align to low border
buf += pagesize; // align to high border
您的编译器自己选择的对齐方式不应比 max_align_t
更宽,但仅此而已。没有禁止要求更广泛的结盟。
因此,要确保 struct
的特定字段位于您希望的边界上,您只需使用 _Alignas
。只要您要求的值是 2 的幂,并且您的编译器允许特定的对齐方式,所有这些都是明确定义的。如果不是,你的编译器必须抱怨。
这正是在 C11 中添加 _Alignas
的原因之一。