cout消息的顺序与预期不符。

5

当我执行下面的代码时,我对输出结果感到困惑。

代码:

int add(int a, int b)
{
    cout<<"inside int add function"<<endl;
    return a+b;
}

float add(float a, float b)
{
    cout<<"inside float add function"<<endl;
    return a+b;
}

int main()
{
    cout<<add(10.0f,20.0f)<<endl<<add(20,50); 
    return 0;
}

输出:

inside int add function
inside float add function
30
70

我不明白cout消息的顺序是如何在控制台中打印的。但我期望上面的程序输出如下:

inside float add function
30
inside int add function
70

有人可以解释一下上述行为吗?


看起来编译器在执行 cout 之前只是评估了这两个函数。所以你看到它先运行了 int add 函数,然后是 float add 函数,最后才是 cout - cf-
这是一种编译器优化,与 return Something(getWhatever(), getWhatever()); 相同,编译器有时会交换两个调用。 - user1551592
可能是重复的问题:cout << order of call to functions it prints? - edmz
2
你认为一个输出比另一个“必需”有什么原因吗?你的期望是合理的,但编译器可以自由地做一些与我们期望不同的事情,除非我们坚持要求它不这样做。你认为你得到的结果被禁止了吗?如果你执行 add(1,2)+add(1.0,2.0),那么对 add 的调用可以以任何顺序发生,对吧? - David Schwartz
2个回答

7

你代码中的这行:

cout<<add(10.0f,20.0f)<<endl<<add(20,50);

编译器将把它翻译成:

operator<<(operator<<(operator<<(cout,add(10.0f,20.0f)),endl),add(20,50));

由于函数参数的计算顺序与标准没有规定,所以在operator<<(operator<<(cout,add(10.0f,20.0f)),endl)之前,add(20,50)会被先计算。

1

该行代码cout<<add(10.0f,20.0f)<<endl<<add(20,50);预计会输出以下内容:

inside int add function
inside float add function
30
70

那是因为要将内容打印到cout时,首先调用add(10.0f, 20.0f)并将输出存储到一个内部变量中,然后调用add(10, 20)并将输出存储到另一个内部变量中,最后才会打印返回的值。类似这样:
float a = add(10.0f, 20.0f);
int b = add(10, 20);
cout << a << endl << b;

在这种情况下,如果您想按照自己的意愿打印,请先打印一个函数,然后再打印另一个函数:
cout << add(10.0f, 20.0f) << endl;
cout << add(10, 20);

不是另一个内部变量,它可以与另一个变量相同,编译器可以自由选择第二个调用是第一个还是第二个等等。此外,它并不是“内部”的,它只是生成的汇编代码的样子,所以如果它将第一个存储在“内部”变量中,并决定在第一个之后打印第二个,则会像这样:mov REG,std :: ostream; USE OPERATOR << 在REG上进行第一次操作,使用OPERATOR << ON REG FOR 2ND - user1551592
我知道“内部变量”被称为寄存器,但我这样称呼是为了避免进入汇编的复杂世界。 - melchor629
如果您使用C++代码进行解释,例如 std::ostream& out; out << a; out << b;,会更好理解。 - user1551592

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接