"reinterpret_cast"一个"T*"到"T(*)[N]&q
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;
这是未定义的行为吗?我认为是的。
a.data()
返回一个int*
,这与int(*)[8]
cpp首选项上的类型别名规则似乎表明
reinterpret_cast
无效作为一名程序员,我知道
。a.data()
指向的内存位置是8
int
对象的数组
我缺少什么规则使这个reinterpret_cast
有效吗?
数组对象及其第一个元素不是指针可相互转换*的,因此reinterpret_cast
的结果是"指向 8int
数组的指针"类型的指针,其值是"指向a[0]
的指针">1。换句话说,尽管有类型,它实际上并不指向任何数组对象。
然后,代码将数组到指针的转换应用于取消引用此类指针(作为索引表达式(*p)[0]
)2的一部分所产生的左值。仅当左值实际引用数组对象3时,才会指定该转换的行为。由于本例中的左值没有,因此行为未由省略4定义。
*如果问题是"为什么数组对象及其第一个元素不可指针互转换?",已经有人问过:指针可互换性与具有相同地址。
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]:未定义的行为是"本文档不强加任何要求的行为",包括"当本文档省略任何明确的行为定义时"。
是的,行为是未定义的。
int*
(返回类型a.data()
)与int(*)[8]
不同,因此您违反了严格的别名规则。
当然(这更有利于未来的读者),
int* p = a.data();
是完全有效的,随后的表达式p + n
也是如此,其中整型n
介于 0 和 8 之间(含 0 和 8)。
- 如何创建一个CMake变量,除非显式重写,否则使用默认值
- 删除一个线程上有数百万个字符串的大型哈希映射会影响另一个线程的性能
- 为什么两个不同的未命名名称空间可以共存于一个cpp文件中
- 运行同一解决方案的另一个项目的项目
- 挂起和取消挂起一个文件DLL
- 用C++中的一个变量定义一个常量
- 函数向量_指针有不同的原型,我可以构建一个吗
- 在c++中用vector填充一个简单的动态数组
- 如何在选项卡视图Qt中设置一个新项目,并保存以前的项目
- 预处理器:插入结构名称中的前一个行号
- 我在c++代码中生成了一个运行时#3异常
- 我想将一个对T类型的非常量左值引用绑定到一个T类型的临时值
- 从链接列表c++中删除一个项目
- 告诉一个 const char 数组,除了编译时 C 样式的字符串外,它不以 '