©
本文档使用
php.cn手册 发布
在翻译单元的顶层(即预处理程序之后包含所有#includes 的源文件),每个 C 程序都是一系列声明,声明具有外部链接的函数和对象。这些声明被称为外部声明,因为它们出现在任何函数之外。
extern int n; // external declaration with external linkageint b = 1; // external definition with external linkagestatic const char *c = "abc"; // external definition with internal linkageint f(void) { // external definition with external linkage int a = 1; // non-external return b; }static void x(void) { // external definition with internal linkage}
使用外部声明声明的对象具有静态存储持续时间,因此不能使用auto
或register
指定符。由外部声明引入的标识符具有文件范围。
暂定定义为外部声明没有初始化,并且或者没有存储类说明或与说明符static
。
一个初步的定义是,可能会或可能不会作为一个定义的声明。如果在同一翻译单元中早或晚时发现实际的外部定义,那么暂定义只是作为声明。
int i1 = 1; // definition, external linkageint i1; // tentative definition, acts as declaration because i1 is definedextern int i1; // declaration, refers to the earlier definition extern int i2 = 3; // definition, external linkageint i2; // tentative definition, acts as declaration because i2 is definedextern int i2; // declaration, refers to the external linkage definition
如果在同一翻译单元中没有定义,那么暂定义定义就像初始化程序= 0
(或者对于数组类型= {0}
)的实际定义一样。
int i3; // tentative definition, external linkageint i3; // tentative definition, external linkageextern int i3; // declaration, external linkage// in this translation unit, i3 is defined as if by "int i3 = 0;"
与 extern 声明不同,如果前一个声明确定了标识符的链接,那么暂定义可能与另一个同一标识符声明不相关。如果同一个标识符的两个声明在范围内并且具有不同的链接,则行为是未定义的:
static int i4 = 2; // definition, internal linkageint i4; // Undefined behavior: linkage disagreement with previous lineextern int i4; // declaration, refers to the internal linkage definition static int i5; // tentative definition, internal linkageint i5; // Undefined behavior: linkage disagreement with previous lineextern int i5; // refers to previous, whose linkage is internal
内部联系的初步定义必须具有完整的类型。
static int i[]; // Error, incomplete type in a static tentative definitionint i[]; // OK, equivalent to int i[1] = {0}; unless redeclared later in this file
每个翻译单元可以具有内部连接(static
全局)的每个标识符的零或一个外部定义。
如果在非 VLA(自C99以来),sizeof 或 alignof(自C11以来)以外的任何表达式中使用具有内部链接的标识符,则翻译单元中该标识符必须有且仅有一个外部定义。
整个程序可能具有零或一个外部定义,每个标识符(除了内联函数外)(自C99以来)都带有外部链接。
如果除了非 VLA(自C99以来),sizeof 或 alignof(自C11以来)之外的任何表达式中使用带有外部链接的标识符,则整个程序中某处必须有唯一的外部定义。
有关内联函数定义的详细信息,请参阅内联。
extern
使用文件范围声明查看关键字含义的存储持续时间和链接。
请参阅声明和定义之间区别的定义。
为了标准化各种 C89之前的方法,我们发明了暂时的定义,以通过内部链接转发声明标识符。
C11 standard (ISO/IEC 9899:2011):
6.9 External definitions (p: 155-159)
C99 standard (ISO/IEC 9899:1999):
6.9 External definitions (p: 140-144)
C89/C90 standard (ISO/IEC 9899:1990):
3.7 EXTERNAL DEFINITIONS