4

考虑下面的 C 程序:

#include <stdio.h>

int f() {
  printf("f");
  return 1;
}

int g() {
  printf("g");
  return 2;
}

int main() {
  return f() + g();
}

根据 C 标准,该程序没有单一的确定性行为,因为main函数中的 sum 包含两个子表达式,以及 C99 标准的以下摘录:

§6.5 (...) 子表达式的求值顺序和副作用发生的顺序均未指定。

因此,打印fggf都是该程序的有效输出。在实践中,给定的编译器将选择一个固定的评估顺序(例如,在这种情况下,gcc 从左到右),但如果我想可靠地比较不同编译器之间的输出,我需要确保我的程序有一个定义的行为。

我的问题是:最简单的方法是什么?有没有办法避免包含临时变量(例如,int tmp = f(); return tmp + g();)?

4

3 回答 3

2

答案是直接而简单的:避免未指定的行为。

对于您的示例情况,如果返回值main无关紧要,您可以使用:

return f(), g();

逗号运算符可以确保操作数从左到右执行。

如果您需要 的值f() + g(),则需要使用临时变量。

于 2013-08-22T14:22:57.383 回答
1

不是来自标准;最简单的方法是使用临时变量。

于 2013-08-22T14:21:19.147 回答
1

要强制执行评估顺序,您需要在函数调用之间有一个序列点。

最简单的方法是使用局部变量来存储中间结果。

除非您有深度递归或极其严格的内存限制,否则这很少会成为问题。

于 2013-08-22T14:40:46.093 回答