c++ 为什么“alignas”说明符不能严格按1字节边界对齐两个字节的缓冲区?

polhcujo  于 2023-08-09  发布在  其他
关注(0)|答案(1)|浏览(114)

谁能解释一下为什么使用说明符alignas不能在堆栈上创建包含2个字节的缓冲区,并严格按照指定的对齐方式对齐(不多也不少)?
为了清楚我在这里的意思是代码片段:

#include <cassert>
#include <cstddef>
#include <cstdint>

int main()
{
    // create buffer on stack which contains 2 bytes and aligned by boundary of 1 byte
    alignas(1) std::byte buf[2]{};

    // convert pointer to first byte in the buffer to unsigned integer
    const auto buf_ptr_as_uint = reinterpret_cast<std::uintptr_t>(buf);

    // expect that address of first byte in the buf aligned by boundary of 1 byte(not 2)
    // namely I expect that last bit of buf_ptr_as_uint should be equal to 1
    // but this is not true. assert is always being triggered.
    assert((buf_ptr_as_uint & 1));
}

字符串
我知道任何由2个字节的边界对齐的地址已经由1个字节的边界对齐。但即便如此,我还是希望“alignas”能够根据指定的对齐方式精确对齐我的缓冲区,特别是考虑到std::byte的对齐要求应该允许满足我的意愿,严格按照1字节边界对齐buf
所以我的问题是:为什么alignas是这样工作的?有没有一种方法可以强制编译器严格按照指定的对齐方式对齐缓冲区(除了分配更大的缓冲区和跳过其中的字节)?还是我错过了什么

gmxoilav

gmxoilav1#

alignas只指定对象的地址必须对齐 * 至少像它指定的那样严格 *。
为什么Alignas以这种方式工作?
因为alignas的目的是确保缓冲区/存储器可用于放置具有特定对齐要求的对象。因此,缓冲区是否也为其他具有更高对齐要求的类型对齐并不重要(即使它这样做了,通常你希望让你的内存为更多类型对齐,而不是更少类型)。
对于alignas说明符中规定的具有更高对齐要求的类型,故意不对齐并可能迫使编译器在此过程中浪费空间的意义是什么?我没有看到任何用例。
有没有一种方法可以强制编译器严格按照指定的对齐方式对齐缓冲区(除了分配更大的缓冲区和跳过其中的字节)?
没有你所建议的就是做这件事的方法。编译器也不能以其他方式实现它。

相关问题