C 与 C++ 中的外部函数

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/11712707/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 15:27:36  来源:igfitidea点击:

Extern functions in C vs C++

c++c

提问by Cartesius00

In *.hheader files of a Clibrary, should one declare functions

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

extern void f();

// or only 

void f();
  1. when using only in C
  2. when using from C++.
  1. 仅在使用时 C
  2. 使用时C++

回答by AnT

There's [almost] never any need to use the keyword externwhen declaring a function, either in C or in C++. In C and in C++ all functions have external linkage by default. The strange habit of declaring functions in header files with externprobably has some historical roots, but it has been completely irrelevant for decades already.

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

There's one [obscure?] exception from the above in C, which is probably not directly related to what you are asking about: in C language (C99) if in some translation unit a function is defined as inlineand also declared as extern(an explicit externis used) then the inline definition of that function also serves as an external definition. If no declarations with explicit externare present in the translation unit, then the inline definition is used as "internal" definition only.

在 C 中,上面有一个 [晦涩的?] 异常,这可能与您要问的内容没有直接关系:在 C 语言 (C99) 中,如果在某个翻译单元中,函数被定义为inline并且还声明为extern(显式extern是使用)然后该函数的内联定义也用作外部定义。如果extern翻译单元中不存在显式声明,则内联定义仅用作“内部”定义。

P.S. There's such thing as extern "C"in C++, but that is a completely different matter.

PSextern "C"在 C++ 中有这样的东西,但那是完全不同的事情。

回答by Jonathan Leffler

In header files of a C library, should one declare functions:

extern void f();
// or only
void f();

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

extern void f();
// or only
void f();

Issue 1: Semantics

问题 1:语义

In a C++ program, the functions are declared as functions returning no value and taking no arguments.

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

In a C program, the functions are declared as functions returning no value and taking an indeterminate but not variable-length list of arguments.

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

To get the 'no arguments' meaning in C, use one of:

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

extern void f(void);
void f(void);

The same notation also means the same thing in C++, though for pure C++ code, using voidin the argument list is not idiomatic (do not do it in pure C++ code).

相同的符号在 C++ 中也意味着同样的事情,但对于纯 C++ 代码,void在参数列表中使用不是惯用的(不要在纯 C++ 代码中使用)。

Issue 2: Inter-working between C and C++

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

Tricky, but the normal rule would that you should declare the functions to C++ code as extern "C". To use the same source code for both, you then need to test the __cplusplusmacro. You'd normally do something like:

棘手,但通常的规则是您应该将 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

The options and variations are manifold, but the header can be used by both C and C++.

选项和变化是多种多样的,但 C 和 C++ 都可以使用头文件。

The macros would normally be defined in one general-purpose header that's used everywhere, and then the particular header would ensure that the general purpose header is included and then use the appropriate form of the macro.

宏通常定义在一个无处不在的通用标头中,然后特定标头将确保包含通用标头,然后使用宏的适当形式。

Issue 3: Style

问题 3:风格

Formally, there is no need for the externnotation before a function declaration. However, I use it in headers to emphasize that it is a declaration of an externally defined function, and for symmetry with those (rare) occasions when there is a global variable declared in the header.

形式上,extern在函数声明之前不需要符号。但是,我在头文件中使用它是为了强调它是外部定义函数的声明,并且与在头文件中声明的全局变量的那些(罕见)场合对称。

People can, and do, disagree over this; I go with the local rules — but when I'm the rule-maker, the externis included in a header.

人们可以而且确实对此持不同意见;我遵循当地规则——但是当我是规则制定者时,extern它包含在标题中。

回答by steffen

For general use declare as

一般用途声明为

#ifdef __cplusplus
extern "C" {
#endif
  void f(void);
#ifdef __cplusplus
}
#endif

Otherwise, externis obsolete.

否则extern就过时了。

回答by ATaylor

The latter is perfectly fine, since it's only a function definition, which tells those, who include this header: 'There's a function with this prototype somewhere around here'

后者非常好,因为它只是一个函数定义,它告诉那些包含这个标题的人:'这里有一个带有这个原型的函数'

In this context, functions differ clearly from variables, but that's a different matter. Make sure though, that you do not include the function body, unless you declare it 'inline' or as part of a class definition (C++) or as a 'template function' (also C++).

在这种情况下,函数与变量明显不同,但那是另一回事。但是请确保您不包含函数体,除非您将其声明为“内联”或作为类定义 (C++) 的一部分或作为“模板函数”(也是 C++)。

回答by Maksim Skurydzin

Specifying extern in function prototype has no effect, since it is assumed by default. Whenever a compiler sees a prototype, it assumes a function is defined somewhere else (in the current or another translation unit). This holds for both of the languages.

在函数原型中指定 extern 没有效果,因为它是默认假设的。每当编译器看到原型时,它就假定在其他地方(在当前或另一个翻译单元中)定义了一个函数。这适用于两种语言。

The following thread has some useful comments in general about extern.

以下线程对 extern 有一些有用的评论。

Effects of the extern keyword on C functions

extern 关键字对 C 函数的影响