CppCoreGuidelines ES.44 代码的正确与否不应该基于函数参数的求值顺序
18 April 2023
“Don’t depend on order of evaluation of function arguments”
理由
因为函数参数的求值顺序是未定义的行为。
注意
C++17 强化了求值顺序规则:一般都是从左到右,除了赋值操作是从右到左。但是没有定义函数参数列表的求值顺序规则。
例子
int i = 0; void f(int a, int b) { cout << "a= " << a << ", b= " << b; } int main() { f(++i, ++i); return EXIT_SUCCESS; }
a= 2, b= 1
在C++17之前,以上代码行为是未定义的。所以任何结果都有可能,比如 f(2,
2)
。从C++17开始,以上代码不能有未定义行为,但是没有指明哪个参数先求值。所以 f
的调用可能成了f(1, 2)
也可能是f(2, 1)
,但是不同编译器可以自由选择以哪种方式求值。
例子
重载操作符可能导致求值顺序问题:
f1()->m(f2()); // m(f1(), f2()) cout << f1() << f2(); // operator<<(operator<<(cout, f1()), f2())
在C++17中,这个例子按照预期求值:从左到右。赋值操作从右到左。
f1() = f2(); // undefined behavior in C++14; in C++17, f2() is // evaluated before f1()
强化
好的代码分析工具能够提出告警