问题 在c ++中引用变量的更改[重复]


这个问题在这里已有答案:


5532
2018-05-15 19:33


起源

是, y 只是一个参考 x所以 y++ 实际上正在修改 x, y 没有自己的价值。 - Remy Lebeau


答案:


您有未定义的行为,因为您的操作在两个连续之间 序列点 (函数参数评估之间没有序列点)。您可以将序列点松散地视为“时间”标记,并且在两个连续的标记之间不允许多次修改同一个变量。

基本上你的代码相当于

std::cout << x << x++; // undefined behaviour

以来 y 只是一个参考(别名) x

1.9程序执行[intro.execution] (强调我的)

14)每一个 价值计算 和 副作用 与...相关联   full-expression在每个值计算和side之前排序   与要评估的下一个完整表达式相关联的效果。

15)除非另有说明, 评估个人的操作数   运算符和单个表达式的子表达式是   未测序。 [注意:在不止一次评估的表达式中   在执行程序期间,无序和不确定   不需要执行其子表达式的有序评估   始终在不同的评估中。 - 结束说明]价值   运算符操作数的计算在之前排序   值计算运算符的结果。 如果对a有副作用   标量对象相对于另一个副作用而言是无序的   相同的标量对象或使用值的值计算   相同的标量对象,它们不是潜在的并发(1.10),   行为未定义。 [注:下一节强制类似,   但对潜在的并发计算有更复杂的限制。   -endnote]

在调用函数时(无论函数是否为内联函数),每次调用   值计算和与任何参数相关的副作用   表达式,或使用指定被调用的后缀表达式   函数,在执行每个表达式之前排序或   被调用函数体中的语句。 [注意:价值   与不同参数相关的计算和副作用   表达式没有排序。 - 尾注]每一次评价   调用函数(包括其他函数调用)不是   否则在执行之前或之后专门排序   被调用函数的主体是不确定地被排序的   执行被调用的函数.9 C ++中的几个上下文   导致函数调用的评估,即使没有相应的   函数调用语法出现在翻译单元中。 [例如:   对new-expression的评估调用一个或多个分配和   构造函数;见5.3.4。再举一个例子,调用一个   转换函数(12.3.2)可能出现在没有的情况下   出现函数调用语法。

有关: https://stackoverflow.com/a/10782972/3093378


15
2018-05-15 19:36



我认为你没有额外的,它们在相同的两个序列点之间(即两个操作之间没有序列点) - Borgleader
@Borgleader谢谢,纠正。 - vsoftco
我不相信这对于参考文献来说是完全正确的。毕竟,如果程序员收到两个引用作为参数,他怎么知道它们是否是别名?我不确定引用操作的规则是否与常规变量相同。 - Puppy
@Puppy我同意客户不知道是否 a 和 b 引用相同的对象,但如果它们发生,那么我相信编译器在内部将它们视为引用对象的两个(不同的)指针。是否修改了指向连接序列点之间相同对象的指针?我记得标准清楚地提到了“序列点之间的副作用”,所以你会有副作用。编辑我认为它与标准相关的东西。 - vsoftco
@Puppy这正是它的原因 未定义的行为 。如果标准改变了那么 cout << c << c++ 具有明确定义的语义,然后编译器必须使函数失望 f(int &x, int &y) { cout << x << y++; }。就目前而言,编译器可以假设x和y在为该函数生成代码时不会别名。程序员可以测试一下 &x == &y 如果他/她想知道。 - M.M