c - extern 关键字对 C 函数的影响

标签 c syntax standards

在 C 中,我没有注意到在函数声明之前使用的 extern 关键字有任何影响。 起初,我认为在单个文件中定义 extern int f();强制您在文件范围之外实现它。然而我发现两者:

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

extern int f() {return 0;}

编译得很好,没有来自 gcc 的警告。我使用了gcc -Wall -ansi;它甚至不接受 // 评论。

在函数定义之前使用extern有什么影响吗?或者它只是一个可选关键字,对函数没有副作用。

在后一种情况下,我不明白为什么标准设计者选择在语法中添加多余的关键字。

编辑:澄清一下,我知道变量中有 extern 的用法,但我只是询问 中的 extern功能

最佳答案

我们有两个文件,foo.c 和 bar.c。

这是 foo.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;
}

现在,这是 bar.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 之间没有共享 header ,但是 bar.c 在链接时需要在 foo.c 中声明一些内容,而 foo.c 在链接时需要 bar.c 中的一个函数已链接。

通过使用“extern”,您可以告诉编译器,它后面的任何内容都将在链接时找到(非静态);不要在当前 channel 中为其保留任何内容,因为稍后会遇到它。函数和变量在这方面受到同等对待。

如果您需要在模块之间共享一些全局变量并且不想将其放在 header 中/初始化它,这非常有用。

从技术上讲,库公共(public) header 中的每个函数都是“extern”,但是将它们标记为“extern”几乎没有任何好处,具体取决于编译器。大多数编译器可以自己解决这个问题。正如您所看到的,这些函数实际上是在其他地方定义的。

在上面的例子中,main()只会打印一次hello world,但会继续输入bar_function()。另请注意,bar_function() 在此示例中不会返回(因为它只是一个简单的示例)。想象一下当信号被服务时 stop_now 被修改(因此, volatile ),如果这看起来不够实用。

外部对于诸如信号处理程序、您不想放入 header 或结构中的互斥锁等非常有用。大多数编译器都会进行优化以确保它们不会为外部对象保留任何内存,因为他们知道他们会将其保留在定义对象的模块中。然而,同样,在对公共(public)函数进行原型(prototype)设计时,使用现代编译器来指定它没有什么意义。

关于c - extern 关键字对 C 函数的影响,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52642015/

相关文章:

c# - 将 null 转换为对象?

css - 我应该使用绝对字体大小(小、中、大等)吗?

gcc - 编译器的错误如何标准化?

C# 尝试/捕捉/最后

c++ - mprotect:如何获取导致保护违规的指令?

c - 为什么 GTK+ 定义 TRUE 和 FALSE?

syntax - OCaml 显式类型签名

c - 需要帮助了解位重置功能

c - GtkAboutDialog 图标未加载?

java - 使用三元运算符将字符串转换为整数