考虑一下:
int main(int, char **) {
int variable = 21;
int array[1] = {21};
using ArrayOf1Int = int[1];
(*reinterpret_cast<ArrayOf1Int *>(&variable))[0] = 42;
*reinterpret_cast<int *>(&array) = 42;
return 0;
}
我刚才是不是违反了严格的别名规则 https://stackoverflow.com/a/7005988/1116364?
或者,如这条评论 https://stackoverflow.com/questions/39376813/is-the-stdarray-bit-compatible-with-the-old-c-array#comment66082963_39377268这让我想到了这个问题:变量是大小为 1 的数组吗?
请注意,我将其标记为语言律师问题。因此我不感兴趣-fno-strict-aliasing
或编译器特定的行为,而是按照标准中的规定。另外,我认为了解 C++03、C++11、C++14 和更新版本之间是否以及如何改变会很有趣。
显然,如果一个对象是大小为 1 的数组的变量,则可以使用对象初始化对大小为 1 的数组的引用:
int variable{21};
int (&array)[1] = variable; // illegal
然而,初始化是非法的。与此相关的条款是第 1 段中所述的第 4 条 [conv](标准转换):
标准转换是具有内置含义的隐式转换。第 4 条列举了完整的此类转换集。
该子句太长,无法在此处引用,但它没有提及将对象转换为任何大小的数组的引用。同样,中的部分reinterpret_cast
(5.2.10 [expr.reinterpret.cast]) 没有说明任何涉及数组的行为,但在第 1 段中说明了此排除:
...可以使用显式执行的转换reinterpret_cast
下面列出了。不能使用显式执行其他转换reinterpret_cast
.
我认为没有明确的声明表明对象不是一个对象的数组,但有足够的遗漏可以隐式地说明这一点。相关对象和数组的标准给出的保证是,指向对象的指针的行为就好像它们指向大小为 1 的数组(5.7 [expr.add] 第 4 段):
就这些运算符而言,指向非数组对象的指针的行为与指向长度为 1 的数组的第一个元素的指针相同,且对象的类型作为其元素类型。
该语句的存在还意味着数组对象和非数组对象是不同的实体:如果它们被认为是相同的,则不需要从该语句开始。
关于标准的先前(或未来)版本:尽管不同条款中的确切用词可能已经改变,但总体情况没有改变:对象和数组始终是不同的实体,到目前为止,我不知道意图改变这一点。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)