`reinterpret_cast` `T*` 到 `T(*)[N]` 是未定义的行为吗?

Is it undefined behavior to `reinterpret_cast` a `T*` to `T(*)[N]`?

考虑以下场景:

std::array<int, 8> a;
auto p = reinterpret_cast<int(*)[8]>(a.data());
(*p)[0] = 42;

这是未定义的行为吗?我觉得是。

我是否遗漏了使此 reinterpret_cast 有效的任何规则?

是的,行为未定义。

int*a.data() 的 return 类型)与 int(*)[8] 不同,因此您违反了严格的别名规则。

当然(这更多是为了未来读者的利益),

int* p = a.data();

完全有效,随后的表达式 p + n 也是如此,其中整数类型 n 介于 0 和 8 之间(含 0 和 8)。

一个数组对象和它的第一个元素是指针不可相互转换的*,所以reinterpret_cast的结果是一个"pointer to array of 8 int"类型的指针值为"pointer to a[0]"1。换句话说,尽管是类型,但它实际上并不指向任何数组对象。

然后,代码将数组到指针的转换应用于取消引用此类指针(作为索引表达式的一部分 (*p)[0])产生的左值2.该转换的行为仅在左值实际引用数组对象3 时指定。由于这种情况下的左值没有,因此行为未定义为 omission4.


*如果问题是"why is an array object and its first element not pointer-interconvertible?",已经有人问过:.

1参见[expr.reinterpret.cast]/7, [conv.ptr]/2, [expr.static.cast]/13 and [basic.compound]/4

2参见[basic.lval]/6, [expr.sub] and [expr.add]

3[conv.array]: "The result is a pointer to the first element of the array."

4[defns.undefined]:未定义的行为是"behavior for which this document imposes no requirements",包括"when this document omits any explicit definition of behavior".