我有两个文件:
这是我的 Makefile 文件:
现在应该很清楚问题出在哪里了:test2.c中的main()函数调用say_hello()却没有声明它!我运行以下命令,使用gcc编译器:
尽管 *.o 文件已经被编译并链接到可执行文件中。这很奇怪。当我运行 a.out 文件时,看到 main() 成功调用了 say_hello() 函数,而该函数并未在 main 的翻译单元内声明,就好像根本没有任何问题一样,这让我感到惊讶!我推断,由于 say_hello() 没有在 test2.c 中先声明,因此根本不应该被 main() 调用。请注意,我已经添加了对 #include 的注释。这些预处理指令包括函数的声明/原型,将它们的作用域扩展到相应的 *.c 文件中。这就是为什么我们能够使用它们。没有函数声明/原型 == 在该翻译单元中没有作用域,或者我之前一直是这么认为的,直到现在。
"g++ 做了它该做的,并停止了编译过程。但是 gcc 没有这样做!发生了什么?这是 C 编程语言的优点吗?还是编译器的问题?"
test1.c
和 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 的注释。这些预处理指令包括函数的声明/原型,将它们的作用域扩展到相应的 *.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 编程语言的优点吗?还是编译器的问题?"