代码之家  ›  专栏  ›  技术社区  ›  user3429606

将阵列的起始地址对齐为32位的倍数?

  •  0
  • user3429606  · 技术社区  · 8 年前

    #pragma pack(32)
    char array[223];
    #pragma pack
    

    P、 S:为了与32位对齐,地址的最后两位应该是0。

    2 回复  |  直到 8 年前
        1
  •  2
  •   too honest for this site    8 年前

    包装是完全无关的。要对齐静态变量或结构成员(相对于结构开始),请使用标准 _Alignas specifier .

    如果您需要在平台上进行最大对齐(即适合任何类型的对齐),请使用 max_align_t ,对于特定的字节对齐方式,只需将对齐方式指定为常量表达式:

    _Alignas(32 / CHAR_BIT) char a[10];
    

    (如果除法有余数,这将导致问题;您真的是指32吗 字节数 ? 标准不保证一个字节有8位。)

    如果打算将数组强制转换为任何其他类型,则仍然会违反有效类型(也称为严格别名)规则来调用未定义的行为。使用正确的数组类型,并使用该类型中较大的对齐方式或任何您想要的方式,例如使用条件运算符:

    Alignas(_Alignof(int) > 8 ? _Alignof(int) : 8) int a[10];
    
        2
  •  2
  •   chqrlie    8 年前

    定义 char

    union {
        char array[223];
        unsigned long ul;
    } u;
    

    u 将在32位边界上对齐,或者可能在2 if类型的更大幂上对齐 unsigned long 需要它,这在您的系统上非常可能。通过以下方式访问阵列: u.array

    If类型 uint32_t 是可用的,您可以使用它代替 .

    此解决方案并非真正可移植,而是针对不支持 _Alignas 说明符。您的编译器似乎不符合当前(或以前)C标准。

    唯一正确的解决方案是使用 说明符。如果您提供更多的上下文,例如您使用的是什么系统和编译器,以及为什么需要32位对齐,那么可以为您的问题找到更好的解决方案。