【发布时间】:2021-11-22 20:34:37
【问题描述】:
标准在 6.8.6.4 中提供了一个示例:
示例:
struct s { double i; } f(void); union { struct { int f1; struct s f2; } u1; struct { struct s f3; int f4; } u2; } g; struct s f(void) { return g.u1.f2; } /* ... */ g.u2.f3 = f();没有未定义的行为,尽管如果 分配是直接完成的(不使用函数调用来获取 值)。
您能否解释一下为什么在直接分配的情况下会有 UB。这似乎与标准中示例上面的定义相矛盾:
如果表达式的类型与返回类型不同 它出现的函数,值被转换为 赋值给具有函数返回类型的对象。
所以return 的语义和赋值应该是一样的。
【问题讨论】:
-
您是否看到脚注 #175 中提到了关于重叠的差异(6.5.16.1 §3)? “return 语句不是赋值。”我没有搜索标准,但是没有地方定义函数返回值是临时对象吗?
-
@thebusybee:临时对象仅用于返回包含数组的结构。 (因为在引用数组时需要一个对象,因为它必须转换为指针,如
f().array[3]。) -
@EricPostpischil 所以一个积极优化的编译器可能会内联函数并编译一个赋值?嗯,听起来像是一个有趣的实验,并将其与显式赋值的汇编进行比较。
-
@thebusybee 当然我看到了,但脚注不规范......
-
但他们解释文字。 ;-) 在这种情况下,它会导致您想要的答案。
标签: c return language-lawyer