I stumbled upon this behaviour while helping a friend with his homework.
#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;
}
Given this piece of code, gcc-5.4.0-r3 (Gentoo)
returns 1
when compiled with any optimization level. What I find most astonishing is though that gcc compiles without warnings. Only using -Wall
it issues a "control flow may reach end of non-void function" warning.
clang
is a bit more interesting. It generates 0
when compiled without optimizations, but 1
when compiled with optimizations. Contrary to gcc, clang warns the user about the possible control flow error.
According to the C89 standard, this is undefined behaviour. I suspect that gcc (and clang with optimizations) propagate the innermost factorial return to the top, because when the constant changes, so does the return value.
Can someone explain what exactly is happening?