c++ - 在同一行中打印引用变量和更改此变量的函数

标签 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

谁能解释一下为什么我们在这两种情况下会有不同的行为?

最佳答案

在 C++17 之前,在行中:

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

存储在x中的值和 y对于表达式的后半部分,每个表达式都可以在调用 g 之前或之后或之间读取。 .

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

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

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

因此输出将从34 5开始, 但最后一个数字可以是 2 , 720 .这称为未指定的行为

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


注意:一些评论声称存在未定义的行为,但实际上并没有。在C++03术语中,函数调用的入口和导出有一个序列点; y的修改在函数中与 y 的读取分开在 main通过这些序列点之一。在 C++11 中,顺序相同,但术语发生了变化。参见 point 11 here .

关于c++ - 在同一行中打印引用变量和更改此变量的函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51487675/

相关文章:

c++ - 强制 std::string 使用 unsigned char(0 到 255)而不是 char(-128 到 127)

c++ - 从函数双端队列上的迭代器获取函数指针

c++ - 如何验证运行时失败是否是由于生成的线程过多造成的?

c++ - 按照符号链接(symbolic link)并使用 QFileInfo 获取绝对路径

c++ - c++中构建依赖和执行DI

c++ - 使用 std::lower_bound() 打印低于特定值的元素范围

c# - Windows 64 位地址空间

C++ 使用 std::regex 逐行分割字符串

c++ - 在 QT 中创建成功的 SSL 握手的正确方法是什么?

c++ - 如何使用 llvm-10 库在 C++ 中定义 LLVM GlobalValue 变量?