C++表达式中的副作用
昨天,有同学给我看这样的程序:
int fun(int n)
{
if(++n==5)
return n++;
else {
return n*fun(n++);
}
}
问,
fun(1)得多少?咋一看,这不是求 5! 么?再看,
++n==5已经让 n+=1 了,那就应该是这样的:
f(1)
2 * f(2)
3 * f(3)
4 * f(4)
5
答案应该是 120。作为一个悲观的 code warrior,我没有就此停止,我习惯性地把段代码贴进 Emacs,编译了一把,运行结果竟然是……300。我瘫坐在椅子里,听着外面淅淅沥沥的雨声。不是说“*”号是从左到右么?怎么会这样。再看了一眼 K&R 的 TCPL,第53页里表格说的是 associativity,不是 evaluate order。而且就在这一页,作者提到了
C, like most languages, does not specify the order in which the operands of an operator are evaluated.
函数参数的情形也一样。
C++标准 ISO/IEC 14882-2003 chap5.4 也提到
Except where noted, the order of evaluation of operands of individual operators and subexpressions of individual expressions, and the order in which side effects take place, is unspecified.
Unspecified behaviour 和 undefined behaviour 真是 C/C++ 程序员的噩梦。故事如果发生在不使用副作用的函数语言(比如 Scheme)那里,应该就没有这种问题了。
