对象类型具有对齐要求([basic.fundamental], [basic.compound])对地址设置限制 可以分配该类型的对象。
我希望允许C ++编译器假设任何指向T的指针指向正确对齐的T。
e.g。 (如果alignof(int)== 4)
int* p = /* ... */
auto val = p[0];
if ((reinterpret_cast<std::uintptr_t>(p) & 3) != 0) {
// assumed to be unreachable
}
然而,在编译器资源管理器中测试GCC和clang,我没有看到他们中的任何一个做出这个假设。 即使我取消引用指针(如果没有正确对齐肯定会导致UB),也不会产生这种指针值假设。
我认识到指针到整数值的映射是实现定义的,并且编译器可能有一个映射而不是这段代码所假设的映射(尽管我不这么认为)。
我也认识到,生产中的许多代码可能会因为这个假设而中断,解释了为什么目前这些编译器没有完成。
我的问题是:根据标准,编译器可以做出有效假设吗?
如果没有,请引用标准!
编辑:澄清指针被解除引用。
EDIT2:比较alignof()(而不是sizeof())
答案 0 :(得分:1)
是编译器可能假设指针已正确对齐。
让我们暂时假设有一个函数is_aligned
,它测试指针指向的地址是否与其类型正确对齐。
int* p = /* ... */
auto val = p[0];
if (is_aligned(p)) {
// assumed to be unreachable
}
那将是真的。我们从[basic.life]
推断出这一点类型为
T
的对象的生命周期始于:
- 获得
T
类型的正确对齐和大小的存储[...]
因此,不存在具有不正确对齐的对象。 It then follows指针是空指针,无效或指向另一种类型的对象。
通过空指针访问是非法的,access through invalid pointers也是非法的,access to an object of another type †也是如此,它通过未对齐的指针UB进行访问。
†unsigned char
,char
和std::byte