C与C++中的外部函数

Car*_*s00 36 c c++

在库的*.h头文件中C,应该声明函数

extern void f();

// or only 

void f();
Run Code Online (Sandbox Code Playgroud)
  1. 仅在使用时 C
  2. 当使用时C++.

AnT*_*AnT 47

extern在C语言或C++中声明函数时,几乎不需要使用关键字.在C和C++中,默认情况下所有函数都有外部链接.在头文件中声明函数的奇怪习惯extern可能有一些历史根源,但几十年来已经完全无关紧要了.

C语言中有一个[模糊?]异常,它可能与您所询问的内容没有直接关系:在C语言(C99)中,如果在某些翻译单元中,函数被定义为inline 并且也被声明为extern(显式extern是used)然后该函数的内联定义也作为外部定义.如果extern转换单元中不存在带有显式的声明,则内联定义仅用作"内部"定义.

PS extern "C"在C++中有这样的东西,但这是完全不同的事情.

  • @ user827992:我很确定你在谈论`extern"C"`而不是`extern`来声明一个函数. (5认同)
  • 如今,`extern`关键字通常用于通过JNI将C / C ++代码绑定到Java,例如,这是在将C / C ++与Android结合使用时的常见解决方案。 (2认同)

Jon*_*ler 21

在C库的头文件中,应该声明一个函数:

extern void f();
// or only
void f();
Run Code Online (Sandbox Code Playgroud)

问题1:语义学

在C++程序中,函数被声明为函数,不返回值并且不带参数.

在C程序中,函数被声明为函数,它们不返回任何值并采用不确定但不是可变长度的参数列表.

要在C中获得"无参数"含义,请使用以下方法之一:

extern void f(void);
void f(void);
Run Code Online (Sandbox Code Playgroud)

相同的表示法在C++中也意味着相同的东西,但对于纯C++代码,void在参数列表中使用不是惯用的(不要在纯C++代码中这样做).

问题2:C和C++之间的互通

棘手,但通常的规则是你应该将函数声明为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
Run Code Online (Sandbox Code Playgroud)

选项和变体是多方面的,但标题可以由C和C++使用.

宏通常会在一个通用的头文件中定义,这个头文件在任何地方使用,然后特定的头文件将确保包含通用头文件,然后使用适当的宏形式.

问题3:风格

形式上,extern在函数声明之前不需要表示法.但是,我在头文件中使用它来强调它是一个外部定义函数的声明,并且当头部中声明了一个全局变量时,这些(罕见)场合是对称的.

人们可以而且确实不同意这一点; 我遵守当地的规则 - 但是当我是规则制定者时,它extern被包含在标题中.


ste*_*fen 5

一般用途声明为

#ifdef __cplusplus
extern "C" {
#endif
  void f(void);
#ifdef __cplusplus
}
#endif
Run Code Online (Sandbox Code Playgroud)

否则,extern已经过时了.