【发布时间】:2019-07-03 22:12:18
【问题描述】:
以前,在 basic.lval 中,有这个要点:
在其元素或非静态数据成员(递归地包括子聚合或包含的联合的元素或非静态数据成员)中包含上述类型之一的聚合或联合类型,
在当前的draft,已经没有了。
WG21 网站上有一些背景资料:http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p1359r0.html#2051:
7.2.1 [basic.lval] 第 10 段的别名规则改编自 C 并添加了 C++。然而,一些点要么不适用,要么被其他点所包含。例如,在 C 中需要为结构赋值提供聚合和联合类型,在 C++ 中,这是通过 C++ 中的构造函数和赋值运算符完成的,而不是通过访问完整的对象。
谁能给我解释一下,这是什么意思?这个严格的别名规则与 C 中的结构赋值有什么关系?
cppreference 谈到这条规则:
这些项目符号描述了 C++ 中不能出现的情况
我不明白,为什么这是真的。例如,
struct Foo {
float x;
};
float y;
float z = reinterpret_cast<Foo*>(&y)->x;
最后一行似乎与项目符号点描述的一样。它通过一个聚合访问y(一个float),其中包括一个float(成员x)。
有人能解释一下吗?
【问题讨论】:
-
第一个要点无论如何都没有多大意义(在任何一种语言中),所以我很高兴看到它消失了!
-
@M.M 你能解释一下“使用任何一种语言”的说法吗?
-
@LanguageLawyer 在 C 或 C++ 中
-
@M.M 我的意思是为什么它在 C 中没有意义
-
@LanguageLawyer 说你有
struct S { int a; float b; };和float *c = malloc(100);并且 int 和 float 大小相同且没有填充;那么根据该文本,c[0] = c[1] = 0; S s = *(S *)c;不是别名违规,因为floatc[0]由具有float作为其成员的聚合类型访问(不要介意成员的偏移量没有的事实) t对应正在访问的内存)
标签: c++ struct language-lawyer strict-aliasing