假设我们有函数 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
谁能解释一下为什么我们在这两种情况下会有不同的行为?
最佳答案
在 C++17 之前,在行中:
cout << g(g(x, y), y) << ' ' << x << ' ' << y << endl;
存储在x
中的值和 y
对于表达式的后半部分,每个表达式都可以在调用 g
之前或之后或之间读取。 .
请注意表达式 y
在 g
的参数列表中不要读取存储的值:y
是直接绑定(bind)到左值引用函数参数的左值,因此不存在左值到右值的转换。
调用g
具有以下行为,其中 x
和 y
引用 main
中的变量:
- 初始:
x = 5, y = 2
. - 内部调用
g
后:x = 5, y = 7
(调用返回13
)。 - 在外部调用
g
之后:x = 5, y = 20
(调用返回34
)。
因此输出将从34 5
开始, 但最后一个数字可以是 2
, 7
或 20
.这称为未指定的行为。
Since C++17 , <<
的操作数链从左到右排列;现在唯一可能的输出是 34 5 20
.
注意:一些评论声称存在未定义的行为,但实际上并没有。在C++03术语中,函数调用的入口和导出有一个序列点; y
的修改在函数中与 y
的读取分开在 main
通过这些序列点之一。在 C++11 中,顺序相同,但术语发生了变化。参见 point 11 here .
关于c++ - 在同一行中打印引用变量和更改此变量的函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51487675/