【问题标题】:c++ function call within cout statement [duplicate]cout语句中的c ++函数调用[重复]
【发布时间】:2013-06-01 21:31:36
【问题描述】:

我正在学习c++,最近遇到了一个令人困惑的问题,代码如下:

#include <iostream>

using namespace std;

class A {
    public:
        A() { a[0] = 1; a[1] = 0; }
        int a[2];
        int b(void) { int x=a[0];a[0]=a[1];a[1]=x; return x; }
};

int main(void) {
    A a;
    cout<<a.a[0]<<a.a[1]<<endl; //outputs 10
    a.b();
    cout<<a.a[0]<<a.a[1]<<endl; //outputs 01
    a.b();
    cout<<a.a[0]<<a.a[1]<<endl; //outputs 10

    cout << a.b() << //outputs 1
    endl<< a.a[0]<<a.a[1] << endl; //outputs 10???

    cout<<a.a[0]<<a.a[1]<<endl; //outputs 01???
    return 0;
}

前两次调用 b() 的行为符合预期,但是当我在 cout 语句中调用 b() 时,它不会立即切换数组的两个元素,但后来我检查了一下,它已经切换了.

你能帮我理解这种行为吗?谢谢。

【问题讨论】:

  • 请允许我建议您的问题与此问题(以及许多类似问题)重复:stackoverflow.com/questions/10782863/…
  • @jogojapan - 这不是那个问题的重复,因为有一个函数调用会引入一个序列点。
  • @PeteBecker 正如您在回答中所说,这两个评估是无序的(相对于彼此)。由于两者之一对另一个读取的左值有副作用,因此与重复问题中描述的基本情况相同。
  • @jogojapan - 它们不是无序的。它们的序列不确定
  • @PeteBecker 在 1.9/15 C++11 中有一条注释,在函数调用的参数评估上下文中:与不同参数表达式相关的值计算和副作用是无序的我>。它在那里说unsequenced

标签: c++


【解决方案1】:

std::cout &lt;&lt; f() &lt;&lt; g();

两个函数调用的求值顺序未指定;编译器可以调用g() 然后f(),或者它可以调用f() 然后g()

您的代码中的相同内容;编译器可以通过调用a.b()a.a[0] 的值隐藏起来,或者它可以调用a.b() 然后获取a.a[0] 的值。

【讨论】:

  • 不幸的是,另一个答案现在已被删除,但我打算在那里发表评论:它实际上是未定义行为的原因是两个评估之一对左值另一个评估有副作用在看书。标准规定,这种情况必须始终被视为未定义的行为。
  • @jogojapan - 请参考一下?
  • C++11 在 1.9/15 中有:如果标量对象的副作用相对于同一标量对象的另一个副作用或使用相同的标量对象,行为未定义。 在 C++03 中它有点复杂,请参阅一些答案:stackoverflow.com/questions/4176328/…
  • @jogojapan - 对,但我们在这里处理的不是未排序的效果,而是不确定的排序效果。
  • 我们现在有一个双线程讨论 :-) 请参阅我对这个问题的评论。
【解决方案2】:

表达式中的函数求值取决于编译器流操作,例如&lt;&lt;&gt;&gt;。评估x = f1() + f2() 时会出现同样的问题。你不知道哪个会首先被评估,因为它依赖于编译器。

在单独的行中调用它们以排除歧义会更安全。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-02-19
    • 2020-03-30
    • 2022-11-17
    • 2015-04-07
    • 2015-03-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多