【问题标题】:Alterations to reference variables in c++ [duplicate]C ++中引用变量的更改[重复]
【发布时间】:2015-11-26 03:33:12
【问题描述】:
#include <iostream>
using namespace std;

int main()
{
    int x=80;
    int &y=x;
    cout<<"x"<<x<<" "<<"y"<<y++; 
    return 0;
}

上面的代码给了我以下输出:

81 80

谁能解释一下x 的值是如何变成81 的? y 的值是80,后来它增加到81,但是它如何反映在x 中?

是否反映了因为y 是引用变量? 那么xy 中的值应该都被修改了?

【问题讨论】:

  • 是的,y只是对x的引用,所以y++实际上是在修改xy没有自己的价值。

标签: c++ pointers memory-address


【解决方案1】:

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

基本上你的代码相当于

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

因为y 只是x 的引用(别名)。

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

14) 每一个值计算副作用都与一个 全表达式在每个值计算和边之前排序 与要评估的下一个完整表达式相关联的效果。

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

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

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

【讨论】:

  • 我认为你有一个额外的不存在,它们在相同的两个序列点之间(即两个操作之间没有序列点)
  • @Borgleader 谢谢,已更正。
  • 我不认为这对于参考是完全正确的。毕竟,如果程序员收到两个引用作为参数,他怎么知道它们是否有别名?我不确定引用操作的规则是否与常规变量相同。
  • @Puppy 我同意客户端无法知道 ab 是否引用同一个对象,但如果它们碰巧,那么我相信编译器在内部将它们视为两个(不同)指向被引用对象的指针。修改指向连续序列点之间相同对象的指针是否定义明确?我记得标准清楚地提到了“序列点之间的副作用”,所以你在这里会有副作用。用我认为与标准相关的内容进行了编辑。
  • @Puppy 这正是它是 undefined behavior 的原因。如果更改标准以使cout &lt;&lt; c &lt;&lt; c++ 具有明确定义的语义,那么编译器将不得不悲观函数f(int &amp;x, int &amp;y) { cout &lt;&lt; x &lt;&lt; y++; }。就目前情况而言,编译器可以假设 x 和 y 在为该函数生成代码时没有别名。如果程序员想知道,可以测试&amp;x == &amp;y
猜你喜欢
  • 2014-11-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-12-04
  • 1970-01-01
  • 1970-01-01
  • 2021-09-11
相关资源
最近更新 更多