代码:
#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和MSVS2010。不胜感激!
#1 楼
未指定表达式中元素的评估顺序(某些特殊情况除外,例如&&
和||
运算符以及引入序列点的三元运算符);因此,不能保证在test
(对其进行修改)之前或之后都会对foo(test)
进行评估。 如果您的代码依赖于特定的求值顺序,则获取代码的最简单方法是将表达式拆分为多个单独的语句。
#2 楼
这个问题的答案在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 楼
未指定评估顺序。它不是从左到右,从右到左或其他任何方法。不要这样做。
#4 楼
未指定评估顺序,请参见http://en.wikipedia.org/wiki/Sequence_point这与带有operator +示例的示例相同:
考虑两个函数
f()
和g()
。在C和C ++中,+
运算符未与序列点关联,因此在表达式f()+g()
中,有可能先执行f()
或g()
。#5 楼
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
评论
您知道使用||的技巧吗?或&&强制执行<<链中的某个评估顺序?
– alfC
16年5月20日在23:12
不,但是我知道使用;并在换行符之后重复流变量;-)
–意大利Matteo
16年5月21日在3:25
也许使用C ++ 17标准中引入的更改来更新此答案将对以后在此绊脚的人们有所帮助:stackoverflow.com/a/50361417/9385966
– gflegar
18年5月16日在2:12