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

时间:2018-05-23 19:38:53

标签: c++ c scope function-declaration

我有两个文件:test1.ctest2.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>。请注意,我已向make CXX=g++添加了评论。这些预处理程序指令包括函数声明/原型,它们将其范围扩展到相应的* .c文件中。这就是我们能够使用它们的原因。没有函数声明/原型==没有该翻译单元的范围,所以我想到现在。

然后我将上面的代码编译为C ++代码: 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

我在屏幕上收到此错误:

data: { positions: JSON.stringify(pagePosData) }

g ++完成它应该做的事情,并停止编译过程。但是gcc没有这样做!发生了什么事?它是C编程语言的特权吗?这是编译器的问题吗?

1 个答案:

答案 0 :(得分:4)

简单,因为C允许调用未声明的函数而C ++不会。不管怎样,gcc警告你,你可能想要认真对待警告。