答案 0 :(得分:7)
询问*&++i
本身是否具有UB是没有意义的。引用不一定访问i
的存储值(先前或新的),正如您可以通过将其用作引用的初始化表达式所看到的那样。只有涉及右值转换(在这种情况下使用)才有任何问题需要讨论。然后,由于我们可以使用++i
的值,因此我们可以使用*&++i
的值与++i
完全相同的注意事项。
原始问题基本上与i = ++i
有关,与i = *&++i
相同。这是C ++ 03中未定义的行为,因为i
在序列点之间被修改了两次,并且在C ++ 11中定义良好,因为赋值运算符的值在序列之后被排序计算左侧和右侧。
可能需要注意的是,C ++ 98和C ++ 03标准中的非规范性示例是不正确的,将某些正式未定义行为的情况描述为仅仅是未指定的行为。因此,意图一直没有完全清楚。一个好的经验法则是不要依赖语言的这些模糊的角落案例,以避免它们:为了理解代码,不应该成为一名语言律师......
答案 1 :(得分:0)
我认为这个问题只有在我们处理表达式时才有意义:
i = *&++i;
C ++ 03标准中的相关引用将是[expr] / 4:
除非另有说明,否则单个操作员的操作数和个体的子表达式的评估顺序 表达式以及副作用发生的顺序是未指定的。之间的 和下一个序列点标量对象的评估值最多只能修改一次 一个表达。此外,只能访问先前值以确定要存储的值。 对于完整的子表达式的每个允许排序,应满足本段的要求 表达;否则行为未定义。
i = ++i + 1; // the behavior is unspecified
我们可以比较i = *&++i
与i = ++i + 1
的排序,以确定相同的规则会导致两者都未指定。它们都是以下形式的陈述:
i = f(++i);
对于任何函数f
,左侧i
的读数和右侧++i
的副作用相对于每个函数都没有排序其他。因此,未定义的行为。