大家好我今天偶然发现了这段代码,我对于究竟发生了什么以及更具体的顺序感到困惑:
代码:
#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.感谢任何帮助!
答案 0 :(得分:22)
表达式中元素的评估顺序未指定(除了一些非常特殊的情况,例如&&
和||
运算符以及引入序列点);所以,不能保证test
在foo(test)
之前或之后进行评估(修改它)。
如果您的代码依赖于特定的评估顺序,获取它的最简单方法是将表达式拆分为多个单独的语句。
答案 1 :(得分:10)
评估顺序未指定。它不是从左到右,从右到左,或其他任何东西。
不要这样做。
答案 2 :(得分:5)
这个问题的答案在C ++ 17中有所改变。
对重载运算符的评估现在按照与内置运算符(C ++ 17 [over.match.oper] / 2)相同的方式进行排序。
此外,<<
,>>
和下标运算符现在左边的操作数在之前排序,而函数调用的后缀表达式是在评估参数之前排序。
(其他二元运算符保留其先前的排序,例如+
仍然没有排序。)
因此,问题中的代码现在必须输出Value of test is : 0 Return value of function is : 1 Value of test : 1
。但是,“不要这样做”的建议仍然是合理的,因为每个人都需要一些时间才能更新到C ++ 17。
答案 3 :(得分:2)
未指定评估顺序,请参阅http://en.wikipedia.org/wiki/Sequence_point
这与使用operator + example的示例相同:
考虑两个函数
f()
和g()
。在C和C ++中,+
运算符与序列点无关,因此在表达式f()+g()
中,有可能首先执行f()
或g()
答案 4 :(得分:0)
c ++参考很好地解释了为什么永远不应该这样做(导致UB或不确定的行为) https://en.cppreference.com/w/cpp/language/operator_incdec
#include <iostream>
int main()
{
int n1 = 1;
int n2 = ++n1;
int n3 = ++ ++n1;
int n4 = n1++;
// int n5 = n1++ ++; // error
// int n6 = n1 + ++n1; // undefined behavior
std::cout << "n1 = " << n1 << '\n'
<< "n2 = " << n2 << '\n'
<< "n3 = " << n3 << '\n'
<< "n4 = " << n4 << '\n';
}
注释
由于所涉及的副作用,内置的增量和减量 必须小心使用运算符,以避免由于以下原因导致的未定义行为 违反排序规则。
在与排序规则相关的部分中,您可以阅读以下内容:
未定义的行为:
1)如果相对于同一标量对象上的另一个副作用,未对标量对象上的副作用进行排序,则行为未定义。
i = ++i + 2; // undefined behavior until C++11
i = i++ + 2; // undefined behavior until C++17
f(i = -2, i = -2); // undefined behavior until C++17
f(++i, ++i); // undefined behavior until C++17, unspecified after C++17
i = ++i + i++; // undefined behavior
2)如果相对于使用同一标量对象的值进行的值计算,对标量对象的副作用未排序,则行为不确定。
cout << i << i++; // undefined behavior until C++17
a[i] = i++; // undefined behavior until C++17
n = ++i + i; // undefined behavior