根据我的理解,
extern
和 static
存储类说明符非常相似(它们都将声明指定为驻留在静态内存中),但是当在任何函数体之外使用时,它们在文件级别的范围不同C程序。例如:
static int a = 42; // Initializes `a` to 42, static memory, internal linkage
static int b; // Initializes `b` to 0, static memory, internal linkage
extern int c = 42; // Initializes `c` to 42, static memory, external linkage
extern int d; // Only provides a symbol for the compiler and linker, external linkage
int e; // Initializes `e` to 0, static memory, external linkage
没有任何说明符的声明通常被称为“暂定声明”,它的工作方式几乎与人们期望的一样
extern int a;
如果它还没有其他含义的话。
然而,当人们使用函数的暂定声明时,情况似乎并非如此:
int a(void); // Only provides a symbol for the compiler and linker, external linkage
extern int a(void); // Only provides a symbol for the compiler and linker, external linkage
这一切都很好,但在我看来,当您考虑以下声明时会出现复杂情况:
static int a(void);
以及
static int a(void);
static int a(void) { ... }
static int b(void);
int b(void) { ... }
static int c(void);
extern int c(void) { ... }
extern int d(void);
static int d(void) { ... }
我对这里发生的事情的最佳猜测是
static int a(void); // Only provides a symbol for the compiler, internal linkage
拆卸似乎证实了这一点。
这是最有意义的,并且与暂定声明所完成的一致,因为默认初始化没有与函数的完美模拟。
这里类比函数定义和对象初始化好像是错误的:
static int obj;
static int obj = 2; // Error in gcc and clang
static int func(void);
static int func(void) { ... } // Valid in gcc and clang
我知道函数定义在某种意义上是特殊的,但通常它们的语义似乎与对象的声明和初始化一致,特别是数组。
静态函数声明甚至是标准 C 语言吗?说明符不匹配函数声明怎么样?