考虑下面的C程序:
#include <stdio.h>
int f() {
printf("f");
return 1;
}
int g() {
printf("g");
return 2;
}
int main() {
return f() + g();
}
根据C标准,该程序没有单一的确定性行为,因为main
函数中的总和包含两个子表达式,以及以下摘录自C99标准:
§6.5(...)子表达式的评估顺序和顺序 发生哪些副作用都是未指明的。
因此,打印fg
和gf
都是此程序的有效输出。在实践中,给定的编译器将选择单个固定的评估顺序(例如,在这种情况下,从左到右的gcc),但如果我想要可靠地比较不同编译器之间的输出,我需要确保我的程序有一个定义的行为。
我的问题是:最简单的方法是什么?有没有办法避免包含临时变量(例如int tmp = f(); return tmp + g();
)?
答案 0 :(得分:2)
答案是直接而简单的:避免未指明的行为。
对于您的示例案例,如果main
的返回值无关紧要,您可以使用:
return f(), g();
逗号运算符可以确保操作数从左到右执行。
如果您需要f() + g()
的值,则需要使用临时变量。
答案 1 :(得分:1)
不符合标准;最简单的方法是使用临时变量。
答案 2 :(得分:1)
要强制执行评估顺序,您需要在函数调用之间设置一个序列点。
最简单的方法是使用局部变量来存储中间结果。
除非您有深度递归或极其严格的内存限制,否则这很少会出现问题。