我是extern概念的新手。今天在工作中我遇到了大量在头文件中声明的外部函数; foo.h.在一堆乱七八糟的文件夹中,我发现了一个foo.c文件,其中包含所述函数的定义,但它没有#include foo.h
。当我回到家时,我决定使用extern存储类示例。在做了一些阅读C&C"这就是我想出来的。
这是我不希望工作的东西。但确实如此。
的main.c
#include <stdio.h>
int data;
int main()
{
data = 6;
printf("%d\n", getData());
data = 8;
printf("%d\n", getData());
return 0;
}
externs.c
int getData()
{
extern int data;
return data;
}
的bash
gcc main.c externs.c -o externs
我认为这不会起作用,因为函数在main之前并未在技术上(或至少是详细的)定义。这是否有效,因为int getData()
的默认存储类是extern
?如果是这样,为什么甚至打扰下面的例子(类似于我在工作中看到的)?
main2.c
#include <stdio.h>
#include "externs.h"
int data;
int main()
{
data = 6;
printf("%d\n", getData());
data = 8;
printf("%d\n", getData());
return 0;
}
externs.h
#ifndef _EXTERNSH_
#define _EXTERNSH_
extern int getData();
#endif
externs.c
int getData()
{
extern int data;
return data;
}
的bash
gcc main2.c externs.c -o externs
答案 0 :(得分:5)
函数隐式extern
。您可以通过将其声明为static
来更改此内容。
你说extern int getData();
与int getData();
相比是多余的,但有些人认为它可以提高代码的清晰度。
请注意,自C99起,您的第一个示例就是格式错误。它在没有声明该函数的情况下调用getData
。在C89中,这执行了一个隐式的int getData();
声明,但是因为C99被删除了。使用编译器开关-std=c99 -pedantic
来测试它。
答案 1 :(得分:4)
默认情况下,GCC版本4.x或更早版本在C89 / C90兼容模式下编译,这不需要在使用前声明函数。推断未声明的函数的返回类型为int
。默认情况下,GCC 5.x或更高版本在C11兼容模式下编译,这需要在使用前声明函数 - 就像C99一样。
鉴于代码编译时没有投诉,我们可以推断您使用的是GCC 4.x。
即便如此,你也没有义务提供完整的原型,尽管你不会愚蠢。我经常用以下选项编译代码:
gcc -std=c11 -O3 -g -Wall -Wextra -Werror -Wmissing-prototypes -Wstrict-prototypes \
-Wold-style-definition -Wold-style-declaration …
我怀疑那里有一些冗余,但是在我开始运行代码之前,这些选项会遇到很多问题。