我有一个全局的数组类型的char。我希望起始地址与32位对齐。当我检查地图文件中的虚拟地址时,它是xxxxxx56H。如何将起始地址对齐为32位的倍数。我需要通用解决方案而不是编译器相关解我试过了
#pragma pack(32)
char array[223];
#pragma pack
但不行。
P.S:为了与32位对齐,最后两位地址应为0。
答案 0 :(得分:1)
包装是完全不相关的。要对齐静态变量或结构成员(相对于struct start),请使用标准_Alignas
specifier。
如果您需要平台上的最大对齐(即适合任何类型的对齐),请使用max_align_t
,对于特定的字节对齐,只需将对齐指定为常量表达式:
_Alignas(32 / CHAR_BIT) char a[10];
(如果除法有余数,这会导致问题;你真的是指32 位或32 字节?标准不能保证一个字节有8位。)
如果您打算将数组强制转换为任何其他类型,则仍会通过违反有效类型(又称严格别名)规则来调用未定义的行为。对阵列使用正确的类型,并使用较大的类型对齐或任何您想要使用的对齐,例如条件运算符:
Alignas(_Alignof(int) > 8 ? _Alignof(int) : 8) int a[10];
答案 1 :(得分:1)
定义在32位边界上对齐的char
数组的一种可移植的方法是:
union {
char array[223];
unsigned long ul;
} u;
如果类型u
需要, unsigned long
将在32位边界上对齐,或者可能是2的更大幂,这在您的系统上是非常可能的。该数组以u.array
的形式访问。没有编译指示,没有C11特定语法,没有编译器特定扩展。
如果类型uint32_t
可用,您可以使用它代替unsigned long
。
这个解决方案不是真正可移植的,而是解决了不支持_Alignas
说明符的过时编译器。您的编译器似乎与当前(或以前的)C标准保持同步。
唯一正确的解决方案是使用_Alignas
说明符。如果您提供更多上下文,例如您使用的系统和编译器以及为什么需要32位对齐,则可以找到更好的解决方案。