c++ - 为什么 C 允许我调用未声明的函数?

标签 c++ c scope function-declaration

<分区>

我有两个文件:test1.c , 和 test2.c ,其中包含 main()功能。

测试1.c:

#include <stdio.h>  // printf() function declaration/prototype

// function definition
void say_hello() {
  printf("\tHello, world!\n");
}

测试2.c:

#include <stdio.h>  // printf() function declaration/prototype
int main() {
  printf("Inside main()\n");
  say_hello();

  return 0;
}

这是我的生成文件:

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> .这些预处理器指令包括函数声明/原型(prototype),它们将它们的范围扩展到相应的 *.c 文件中。这就是我们能够使用它们的原因。没有函数声明/原型(prototype) == 在那个翻译单元中没有范围,或者直到现在我还这么认为。

然后我将上面的代码编译为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 编程语言的特权吗?是编译器的问题吗?

最佳答案

很简单,因为 C 允许调用未声明的函数,而 C++ 不允许。无论哪种方式,gcc 都会警告您,您可能需要认真对待警告。

关于c++ - 为什么 C 允许我调用未声明的函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50496264/

相关文章:

c++ - 在 C++ 中将字符存储到字符串中

c++ - 如何确保从我的派生类调用纯虚方法?

c - 庆典 : cannot execute binary file

在 C 中将二进制格式字符串转换为 int

c - 在成员的赋值结构中取消引用指向不完整结构类型的指针

Javascript:访问正确的范围 "under"apply(...)

javascript - 继承时原型(prototype)方法中的“this”未按预期解析

c++ - 仅针对指定类型之一运行 typed_test

javascript - 我可以在匿名范围内更改 Javascript 闭包中引用的函数吗

c++ - 调试时如何在VS Code的集成终端中查看C程序的输出