首页 文章

使用std :: cout评估参数的顺序

提问于
浏览 384
10

大家好我今天偶然发现了这段代码,我对于究竟发生了什么以及更具体的顺序感到困惑:

代码:

#include <iostream>

bool foo(double & m)
{
    m = 1.0;
    return true;
}

int main()
{
    double test = 0.0;
    std::cout << "Value of test is : \t" << test << "\tReturn value of function is : " << foo(test) <<  "\tValue of test : " << test << std::endl;
    return 0;
}

输出是:

Value of test is :      1       Return value of function is : 1 Value of test : 0

看到这一点,我会假设在调用函数之前打印出最正确的参数 . 所以这是对的左评价?在调试期间,虽然似乎在输出之前调用该函数,这是我所期望的 . 我正在使用Win7和MSVS 2010.任何帮助表示赞赏!

4 回答

  • 21

    这个问题的答案在C 17中有所改变 .

    对重载运算符的评估现在按照与内置运算符(C 17 [over.match.oper] / 2)相同的方式进行排序 .

    此外, <<>> 和下标运算符现在在左边的操作数之前排序,并且在评估参数之前对函数调用的后缀表达式进行排序 .

    (其他二元运算符保留其先前的排序,例如 + 仍然未被排序) .

    所以问题中的代码现在必须输出 Value of test is : 0 Return value of function is : 1 Value of test : 1 . 但是建议"Don't do this"仍然是合理的,因为每个人都需要一些时间来更新到C 17 .

  • 10

    评估顺序未指定,请参阅http://en.wikipedia.org/wiki/Sequence_point

    这与使用运算符示例的示例相同:

    考虑两个函数f()和g() . 在C和C中,运算符与序列点无关,因此在表达式f()g()中,可能首先执行f()或g() .

  • 3

    表达式中元素的评估顺序是未指定的(除了一些非常特殊的情况,例如 &&|| 运算符以及引入序列点的三元运算符);所以,不能保证在 foo(test) 之前或之后评估 test (它会修改它) .

    如果您的代码依赖于特定的评估顺序,获取它的最简单方法是将表达式拆分为多个单独的语句 .

  • 2

    评估顺序未指定 . 它不是从左到右,从右到左,或其他任何东西 .

    不要这样做 .

相关问题