在 C++ 中,在函数声明之前调用它是一个编译器错误。但在 C 中,它可能会编译。
#include<stdio.h>
int main()
{
foo(); // foo() is called before its declaration/definition
}
int foo()
{
printf("Hello");
return 0;
}
我试过并且知道它是正确的,但我无法理解背后的原因。任何人都可以解释编译过程实际上是如何发生的以及两种语言的不同之处。
最佳答案
事实是代码“编译”为 c程序并不意味着你可以做到。编译器应该警告函数 foo()
的隐式声明。
在这种特殊情况下,隐式声明将声明一个相同的 foo()
并且不会发生任何坏事。
但是假设下面,说这是
main.c
/* Don't include any header, why would you include it if you don't
need prototypes? */
int main(void)
{
printf("%d\n", foo()); // Use "%d" because the compiler will
// implicitly declare `foo()` as
//
// int foo()
//
// Using the "correct" specifier, would
// invoke undefined behavior "too".
return 0;
}
现在假设 foo()
在不同的编译单元1 foo.c 中定义为
foo.c
double foo()
{
return 3.5;
}
它是否按预期工作?
您可以想象如果您使用 malloc()
而不包含 stdio.h 会发生什么,这与我在上面尝试解释的情况几乎相同。
这样做会调用未定义的行为2,因此术语“Works”在这种情况下在可理解的意义上不适用。
这可以编译的原因是因为在很久以前它被c允许标准,即 c89标准。
c++标准从来不允许这样做,所以你不能编译 c++如果您调用的函数在调用之前在代码中没有原型(prototype)(“声明”)。
现代 c编译器会对此发出警告,因为未定义的行为很容易发生,并且由于忘记添加原型(prototype)或包含适当的 header 并不难,所以如果编译器能够对此发出警告,而不是突然出现一个非常无法解释的错误。
1它不能在同一个文件中编译,因为它会被定义为不同的返回类型,因为它已经隐式声明/子>
2从 double
和 int
是不同的类型开始,因此会出现未定义的行为。子>
关于c++ - 为什么我可以在 C 中调用函数而不声明它,但不能在 C++ 中调用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35367208/