在C中,我没有注意到函数声明之前使用的extern关键字的任何效果.

extern int f();
int f() {return 0;}

extern int f() {return 0;}

编译很好,没有来自gcc的警告.我用了gcc -Wall -ansi;它甚至不接受//条 comments .

使用extern-before function definitions有什么影响吗?或者它只是一个对函数没有副作用的可选关键字.

In the latter case I don't underst和 why did the st和ard designers chose to litter the grammar with superfluous keywords.

EDIT:澄清一下,我知道变量中有extern的用法,但我只问functions中的extern.

推荐答案

我们有两份文件,富.c和wine 吧.C

这是福.C

#include <stdio.h>

volatile unsigned int stop_now = 0;
extern void bar_function(void);

int main(void)
{
  while (1) {
     bar_function();
     stop_now = 1;
  }
  return 0;
}

现在,这里是wine 吧.C

#include <stdio.h>

extern volatile unsigned int stop_now;

void bar_function(void)
{
   if (! stop_now) {
      printf("Hello, world!\n");
      sleep(30);
   }
}

正如您所看到的,我们在foo.c和bar.c之间没有共享头,但是bar.c在链接时需要在foo.c中声明一些内容,而foo.c在链接时需要一个来自bar.c的函数.

100

如果您需要在模块之间共享一些全局信息,并且不想将其放入/初始化标头,那么它非常有用.

从技术上讲,库公共头中的每个函数都是"extern",但是根据编译器的不同,将它们标记为extern几乎没有什么好处.大多数编译器都可以自己解决这个问题.正如你所见,这些函数实际上是在其他地方定义的.

在上面的示例中,main()将只打印hello world一次,但会继续输入bar_function().还要注意,在本例中不会返回bar_function()(因为它只是一个简单的示例).试想一下,如果这看起来不够实用,那么当一个信号被服务(因此,是易失性的)时,STOP_NOW会被修改.

外部数对于信号处理程序、您不想放在头或 struct 中的互斥体等非常有用.大多数编译器都会进行优化,以确保它们不会为外部对象保留任何内存,因为它们知道它们将在定义对象的模块中保留内存.然而,同样,在构建公共函数的原型时,使用现代编译器指定它也没有什么意义.

希望这能有所帮助:)

C++相关问答推荐

POSIX文件描述符位置

GLIBC:如何告诉可执行文件链接到特定版本的GLIBC

C由四个8位整数组成无符号32位整数

Linux不想运行编译后的文件

用C++实现余弦函数

这个C程序在工作中途停止获取输入.我收到分段故障(核心转储).我还是不知道问题出在哪里

有什么方法可以将字符串与我们 Select 的子字符串分开吗?喜欢:SIN(LOG(10))

是否需要包括<;errno.h>;才能使用perror?

在移动数组元素时获得意外输出

C代码可以在在线编译器上运行,但不能在Leetcode上运行

循环中的静态变量与块中的变量和循环

使用C++中的字符串初始化 struct 时,从‘char*’初始化‘char’使指针变为整数,而不进行强制转换

为什么这个代码的最后一次迭代不能正常工作?

Ubuntu编译:C中的文件格式无法识别错误

使用 c 中的 write() 函数将非 ASCII 字符写入标准输出

当 n 是我们从用户那里获得的整数时,创建 n 个 struct 参数

为什么 int32_t 和 int16_t 在 printf 输出中具有相同的位数?

UEFI 应用程序中的计时器回调仅在 AMI BIOS 中挂起

为什么 C 字符串并不总是等同于字符数组?

获取 struct 中匿名 struct 的大小