c – `reinterpret_cast`是`T *`到’T(*)[N]`是不确定的行为?
作者:互联网
请考虑以下情形:
std::array<int, 8> a;
auto p = reinterpret_cast<int(*)[8]>(a.data());
(*p)[0] = 42;
这是未定义的行为吗?我觉得是这样的.
> a.data()返回一个int *,它与int(*)[8]不同
> cppreference上的type aliasing rules似乎表明reinterpret_cast无效
>作为程序员,我知道a.data()指向的内存位置是一个包含8个int对象的数组
是否有任何我失踪的规则使这个reinterpret_cast有效?
解决方法:
数组对象及其第一个元素不是指针可互换的*,因此reinterpret_cast的结果是“指向8 int数组的指针”类型的指针,其值为“指向[0]”的指针.换句话说,尽管类型,它实际上并没有指向任何数组对象.
然后代码将数组到指针的转换应用于取消引用这样的指针(作为索引表达式(* p)[0]的一部分)2的左值.仅当左值实际引用数组对象3时才指定该转换的行为.由于此情况下的左值没有,因此omission4的行为未定义.
*如果问题是“为什么数组对象及其第一个元素不是指针可互换的?”,那么它已经被问到:Pointer interconvertibility vs having the same address.
1见[expr.reinterpret.cast]/7,[conv.ptr]/2,[expr.static.cast]/13和[basic.compound]/4.
2见[basic.lval]/6,[expr.sub]和[expr.add].
3[conv.array]:“结果是指向数组第一个元素的指针.”
4[defns.undefined]:未定义的行为是“本文档不强制要求的行为”,包括“当本文档省略任何明确的行为定义时”.
标签:reinterpret-cast,strict-aliasing,c,language-lawyer,c17 来源: https://codeday.me/bug/20191004/1852476.html