我在帮助朋友完成家庭作业时偶然发现了这种行为。
#include "stdio.h"
int f(int n) {
if (n == 0) return 1;
n * f(n-1);
}
int main(void) {
printf("%d\n", f(5));
return 0;
}
给定这段代码,gcc-5.4.0-r3 (Gentoo)
在使用任何优化级别编译时返回1
。我发现最令人惊讶的是gcc 编译时没有警告。只有使用-Wall
它才会发出“控制流可能会达到非空函数结束”的警告。
clang
更有趣。在没有优化的情况下编译时生成0
,但在使用优化进行编译时生成1
。与gcc相反,clang警告用户可能的控制流错误。
根据C89标准,这是未定义的行为。我怀疑gcc(和优化的clang)将最里面的阶乘返回传播到顶部,因为当常量改变时,返回值也是如此。
有人可以解释究竟发生了什么吗?