我有两个文件:test1.c
, and test2.c
,其中包含main()
功能。
test1.c:
#include <stdio.h> // printf() function declaration/prototype
// function definition
void say_hello() {
printf("\tHello, world!\n");
}
test2.c:
#include <stdio.h> // printf() function declaration/prototype
int main() {
printf("Inside main()\n");
say_hello();
return 0;
}
这是我的 makefile:
a.out: test1.o test2.o
$(CXX) -o a.out test1.o test2.o
test1.o: test1.c
$(CXX) -c test1.c
test2.o: test2.c
$(CXX) -c test2.c
现在应该清楚问题出在哪里了:test2.c 中的 main() 函数在没有声明的情况下调用了 say_hello() !
我运行以下命令来使用 gcc 编译器:make CXX=gcc
我在屏幕上收到此警告:
gcc -c test1.c
gcc -c test2.c
test2.c: In function ‘main’:
test2.c:16:3: warning: implicit declaration of function ‘say_hello’ [-Wimplicit-function-declaration]
say_hello();
^
gcc -o a.out test1.o test2.o
尽管 *.o 文件已编译并链接到可执行文件中。这很奇怪。想象一下,当我运行 a.out 文件时,我看到了这一点,我有多惊讶main()
成功调用say_hello()
,一个没有在 main 的翻译单元内部声明的函数,就好像根本没有问题一样!我的理由是,自从say_hello()
之前没有声明过test2.c
,它不应该被允许被调用main()
根本不。请注意,我已将评论添加到#include <stdio.h>
。这些预处理器指令包括函数声明/原型,它们将其范围扩展到相应的 *.c 文件中。这就是为什么我们能够使用它们。没有函数声明/原型 == 在该翻译单元中没有范围,至少我到目前为止是这么认为的。
然后我将上面的代码编译为C++代码:make CXX=g++
我在屏幕上看到此错误:
test2.c: In function ‘int main()’:
test2.c:16:13: error: ‘say_hello’ was not declared in this scope
say_hello();
^
makefile:18: recipe for target 'test2.o' failed
make: *** [test2.o] Error 1
g++ 执行它应该执行的操作,并停止编译过程。但gcc没有这样做!这是怎么回事?这是 C 编程语言的优势吗?是编译器的问题吗?