在C中,我没有注意到在函数声明之前使用extern关键字的任何影响。
首先,我认为当定义extern int f();在单个文件中强制您在文件范围之外实现它。然而,我发现:
extern int f();
int f() {return 0;}
and
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之间没有共享头文件,但是bar.c在被链接时需要在foo.c中声明的东西,而foo.c在被链接时需要bar.c中的函数。
通过使用'extern',你告诉编译器,在链接时,它后面的任何内容都将被找到(非静态);不要在当前通道中为它保留任何东西,因为它将在以后遇到。函数和变量在这方面是平等对待的。
如果你需要在模块之间共享一些全局,而不想把它放在/初始化在一个头文件中,它是非常有用的。
从技术上讲,库公共标头中的每个函数都是“extern”,但根据编译器的不同,将它们标记为“extern”几乎没有任何好处。大多数编译器可以自己解决这个问题。如你所见,这些函数实际上是在其他地方定义的。
在上面的例子中,main()只打印一次hello world,但继续输入bar_function()。还要注意,bar_function()在本例中不会返回(因为这只是一个简单的示例)。想象一下stop_now在信号被服务时被修改(因此是volatile),如果这看起来不够实际的话。
对于信号处理程序、一个你不想放在头文件或结构中的互斥量等,extern非常有用。大多数编译器会优化以确保它们不为外部对象保留任何内存,因为它们知道它们将在定义对象的模块中保留内存。但是,同样,在创建公共函数原型时,使用现代编译器指定它没有什么意义。