我有以下C代码:
int main() {
myFunctionABC(2);
return 0;
}
void myFunctionABC(int n) {
printf("%d\n", n);
}
所以...这段代码正在运行,我不明白为什么。我一直认为C编译器总是需要每个被引用的函数都已经“已知”,否则会使编译过程失败。
为什么这有效?
答案 0 :(得分:6)
在用C语言或C ++调用定义函数之前从未有过任何需求(如问题标题所示)。 C ++和C99(在某些情况下在C89 / 90中)需要的是在调用它们之前声明函数。
至于你的代码......你的代码不“正常”。您可以期待的最好的是您的代码将产生未定义的行为,恰好就像“工作”一样。
首先,代码甚至不会编译为C ++或C99(并且您将问题标记为C和C ++)。 C ++和C99无条件地要求函数在被调用之前被声明。
其次,使用C89 / 90编译器,代码可能编译,但无论如何都会产生上述未定义的行为。即使在C89 / 90中调用可变参数函数(如printf
)而不首先声明它们是非法的 - 它会产生未定义的行为。
对于非变量函数调用它们而不声明它们是正确的 - C89 / 90的隐式声明规则将负责这一点。但是这些规则将使编译器得出结论:未声明的myFunctionABC
函数返回int
,而实际上您将其定义为返回void
- 这种差异也会导致未定义的行为。大多数自尊的编译器至少会警告你这个问题。
答案 1 :(得分:2)
gcc理所当然地抱怨道:
make 4356180
4356180.c:6: warning: conflicting types for ‘myFunctionABC’
4356180.c:2: note: previous implicit declaration of ‘myFunctionABC’ was here
如果我添加-Wall,我会很好地理解这些:
make CFLAGS=-Wall 4356180
4356180.c: In function ‘main’:
4356180.c:2: warning: implicit declaration of function ‘myFunctionABC’
答案 2 :(得分:0)
在实际调用函数原型之前声明函数原型并不是错误的,即使它的定义位于后续位置,但是这是帮助编译器输出的好习惯,请检查{{3} }