我正在阅读 C 项目的来源,并试图辨别为何使用extern
的特定用途。 (注意:http://pleeease.io/play/是相关的,但对于C ++而言,不是C.)假设我有四个头文件,每个头文件声明一个extern const
结构:
extern const struct puppy fido;
此结构在源文件中定义,如下所示:
extern const struct puppy fido;
static const struct puppy *puppies[] = { &fido };
const struct puppy fido = { "fido", 10, 10 };
在源文件中将变量声明标记为extern
是否有某种好处,当这些变量在同一个源文件中定义时?
答案 0 :(得分:3)
唯一的好处是声明和定义之间的任何代码都能够访问变量。除此之外,同一档案中的extern声明毫无意义。
答案 1 :(得分:1)
Lundin是正确的,在这种情况下,extern
不会影响其他源文件中fido
的可见性。在您的示例代码中,它用作前向声明。
C99标准的相关部分,第6.2.2节:
4)对于在范围内使用存储类说明符extern声明的标识符,其中该标识符的先前声明是可见的,如果先前声明指定内部或外部链接,则在后面的声明中标识符的链接是与先前声明中指定的联系相同。如果没有先前声明可见,或者先前声明未指定链接,则标识符具有外部链接。
5)如果函数的标识符声明没有存储类说明符,则确定其链接与使用存储类说明符extern声明的完全相同。如果声明对象的标识符具有文件范围,没有存储类说明符, 它的联系是外在的
在C ++中,行为会有所不同,因为用const
声明的变量是隐式的static
。在C ++中,您需要在第一次使用extern
声明变量,否则其他编译单元将无法找到它。
C ++ 98标准,第3.5.3节:
具有命名空间作用域(3.3.5)的名称具有内部链接(如果它是
的名称)- 显式声明为static或
的对象,引用,函数或函数模板- 显式声明为const的对象或引用,既未显式声明为extern,也未声明为具有外部链接;
答案 2 :(得分:0)
有时候,当你编写一个源文件时,你只需要一个头文件,而不是整个文件。
在源文件中重复extern
声明,不允许在该特定源文件中包含头文件。
这不一定是一种好习惯。
答案 3 :(得分:-1)
extern const struct puppy fido;
// ...
const struct puppy fido = { "fido", 10, 10 };
如果const struct puppy fido = { "fido", 10, 10 };
在2个不同的.c文件中编译,则会失败。在#ifndef
之前和之后应该有endif
和const struct puppy fido = { "fido", 10, 10 };
,以便将其包含一次。
良好做法(通常必须避免使用全局变量)是在.h文件中使用extern
声明,并将变量的定义放在.c中文件。