在与更改此变量的函数相同的行中打印参考变量

时间:2018-07-23 21:52:20

标签: c++

假设我们有函数g:

int g(int x, int& y)
{
    y = y + x++;
    return x + y;
}

主要功能:

int main()
{
    int x = 5;
    int y = 2;
    cout << g(g(x, y), y) << ' ';
    cout << x << ' ' << y << endl;
}

它显示预期结果:

 34 5 20

但是当我重写main时:

int main()
{
    int x = 5;
    int y = 2;
    cout << g(g(x, y), y) << ' ' << x << ' ' << y << endl;
}

它打印

34 5 2

有人可以解释一下为什么在这两种情况下我们会有不同的行为吗?

1 个答案:

答案 0 :(得分:0)

C ++ 17之前的版本:

cout << g(g(x, y), y) << ' ' << x << ' ' << y << endl;

xy中存储的表达式后半部分的值可以分别在调用g之前或之后或之间读取。

请注意,y的参数列表中的表达式g不会读取存储的值:y是直接绑定到左值引用函数参数的左值,因此存在没有左值到右值转换。

g的调用具有以下行为,其中xy指的是main中的变量:

  • 初始:x = 5, y = 2
  • 内部调用g后:x = 5, y = 7(调用返回13)。
  • 外部调用g后:x = 5, y = 20(调用返回34)。

因此,输出将以34 5开头,但是最后一个数字可以是2720。这称为未指定行为

Since C++17<<链的操作数从左到右排序;现在唯一可能的输出是34 5 20


注意:有些评论声称存在未定义的行为,但没有。在C ++ 03术语中,在函数调用的入口和出口处有一个序列点。函数y的修改与ymain的读取被那些序列点之一隔开。在C ++ 11中,顺序是相同的,但是术语有所变化。参见point 11 here