在*.h
库的C
头文件中,应该声明函数
extern void f();
// or only
void f();
C
C++
使用时。答案 0 :(得分:47)
在C语言或C ++中声明函数时,几乎不需要使用关键字extern
。在C和C ++中,默认情况下所有函数都有外部链接。使用extern
在头文件中声明函数的奇怪习惯可能具有一些历史根源,但几十年来它已完全无关紧要。
C中有一个[模糊?]异常,它可能与您所询问的内容没有直接关系:在C语言(C99)中,如果在某个翻译单元中,函数被定义为inline
并且还声明为extern
(使用显式extern
),然后该函数的内联定义也用作外部定义。如果翻译单元中不存在带有显式extern
的声明,则内联定义仅用作“内部”定义。
P.S。在C ++中有extern "C"
这样的东西,但这是完全不同的事情。
答案 1 :(得分:21)
在C库的头文件中,应该声明一个函数:
extern void f(); // or only void f();
在C ++程序中,函数被声明为函数,不返回值并且不带参数。
在C程序中,函数被声明为函数,不返回任何值,并且采用不确定但不是可变长度的参数列表。
要在C中获得“无参数”含义,请使用以下方法之一:
extern void f(void);
void f(void);
相同的表示法在C ++中也意味着相同的东西,但对于纯C ++代码,在参数列表中使用void
不是惯用的(不要在纯C ++代码中这样做)。
Tricky,但通常的规则是你应该将C ++代码的函数声明为extern "C"
。要为两者使用相同的源代码,您需要测试__cplusplus
宏。你通常会这样做:
#ifdef __cplusplus
#define EXTERN_C extern "C"
#define EXTERN_C_BEGIN extern "C" {
#define EXTERN_C_END }
#else
#define EXTERN_C /* Nothing */
#define EXTERN_C_BEGIN /* Nothing */
#define EXTERN_C_END /* Nothing */
#endif
EXTERN_C void f(void);
EXTERN_C_BEGIN
void f(void);
int g(int);
EXTERN_C_END
选项和变体是多方面的,但C和C ++都可以使用标题。
宏通常会在一个通用的头文件中定义,该头文件在任何地方都使用,然后特定的头文件将确保包含通用头文件,然后使用适当的宏形式。
正式地,在函数声明之前不需要extern
表示法。但是,我在头文件中使用它来强调它是一个外部定义函数的声明,以及在标题中声明了全局变量的那些(罕见)场合的对称性。
人们可以而且确实不同意这一点;我遵守当地的规则 - 但是当我是规则制定者时,extern
包含在标题中。
答案 2 :(得分:5)
一般用途声明为
#ifdef __cplusplus
extern "C" {
#endif
void f(void);
#ifdef __cplusplus
}
#endif
否则,extern
已过时。
答案 3 :(得分:1)
后者非常好,因为它只是一个功能定义,它告诉那些包括这个标题的人:'这个原型的功能在这附近的某个地方'
在这种情况下,功能与变量明显不同,但这是另一回事。 但请确保您没有包含功能正文,除非您声明它是内联的'或作为类定义(C ++)的一部分或作为模板函数' (也是C ++)。
答案 4 :(得分:1)
在函数原型中指定extern没有任何效果,因为默认情况下它是假定的。每当编译器看到原型时,它就会假定函数是在其他地方定义的(在当前或另一个转换单元中)。这适用于两种语言。
以下主题一般有关于extern的一些有用的评论。