在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。


当前回答

extern关键字根据环境的不同有不同的形式。如果声明可用,则extern关键字采用前面在翻译单元中指定的链接。在没有任何此类声明的情况下,extern指定外部链接。

static int g();
extern int g(); /* g has internal linkage */

extern int j(); /* j has tentative external linkage */

extern int h();
static int h(); /* error */

以下是C99草案(n1256)的相关段落:

6.2.2 Linkages of identifiers [...] 4 For an identifier declared with the storage-class specifier extern in a scope in which a prior declaration of that identifier is visible,23) if the prior declaration specifies internal or external linkage, the linkage of the identifier at the later declaration is the same as the linkage specified at the prior declaration. If no prior declaration is visible, or if the prior declaration specifies no linkage, then the identifier has external linkage. 5 If the declaration of an identifier for a function has no storage-class specifier, its linkage is determined exactly as if it were declared with the storage-class specifier extern. If the declaration of an identifier for an object has file scope and no storage-class specifier, its linkage is external.

其他回答

内联函数对于extern的含义有特殊的规则。(注意,内联函数是C99或GNU扩展;他们不是原始的C。

对于非内联函数,不需要extern,因为默认情况下它是打开的。

注意,c++的规则是不同的。例如,在要从c++调用的C函数的c++声明上需要extern“C”,关于内联有不同的规则。

extern关键字根据环境的不同有不同的形式。如果声明可用,则extern关键字采用前面在翻译单元中指定的链接。在没有任何此类声明的情况下,extern指定外部链接。

static int g();
extern int g(); /* g has internal linkage */

extern int j(); /* j has tentative external linkage */

extern int h();
static int h(); /* error */

以下是C99草案(n1256)的相关段落:

6.2.2 Linkages of identifiers [...] 4 For an identifier declared with the storage-class specifier extern in a scope in which a prior declaration of that identifier is visible,23) if the prior declaration specifies internal or external linkage, the linkage of the identifier at the later declaration is the same as the linkage specified at the prior declaration. If no prior declaration is visible, or if the prior declaration specifies no linkage, then the identifier has external linkage. 5 If the declaration of an identifier for a function has no storage-class specifier, its linkage is determined exactly as if it were declared with the storage-class specifier extern. If the declaration of an identifier for an object has file scope and no storage-class specifier, its linkage is external.

它没有效果的原因是在链接时,链接器试图解析extern定义(在您的例子中是extern int f())。它是在同一个文件中找到它还是在不同的文件中找到它并不重要,只要找到了它。

希望这能回答你的问题。

在C语言中,函数隐式定义为extern,而不管是否实际声明关键字。

那么,代码:

    int f() {return 0;}

编译器将处理为

    extern int f() {return 0;}

从本质上讲,典型的函数定义与前面带有extern关键字的函数定义之间没有语义上的区别,如本例中所示。你可以在https://www.geeksforgeeks.org/understanding-extern-keyword-in-c/上阅读更深入的解释

据我所知,所有的函数声明默认都被认为是“extern”,所以没有必要显式地指定它。

这并没有使这个关键字无用,因为它也可以与变量一起使用(在这种情况下-这是解决链接问题的唯一解决方案)。但是对于函数,是的,这是可选的。