EXTERN
extern
存储类说明符可以通过以下三种方式之一修改声明,具体取决于上下文:
-
它可用于在不定义变量的情况下声明变量。通常,这将在头文件中用于将在单独的实现文件中定义的变量。
// global scope int x; // definition; x will be default-initialized extern int y; // declaration; y is defined elsewhere, most likely another TU extern int z = 42; // definition; "extern" has no effect here (compiler may warn)
-
它为命名空间范围内的变量提供外部链接,即使
const
或constexpr
会导致它具有内部链接。// global scope const int w = 42; // internal linkage in C++; external linkage in C static const int x = 42; // internal linkage in both C++ and C extern const int y = 42; // external linkage in both C++ and C namespace { extern const int z = 42; // however, this has internal linkage since // it's in an unnamed namespace }
-
如果之前使用链接声明它,则在块范围内重新声明变量。否则,它声明一个带有链接的新变量,该变量是最近的封闭命名空间的成员。
// global scope namespace { int x = 1; struct C { int x = 2; void f() { extern int x; // redeclares namespace-scope x std::cout << x << '\n'; // therefore, this prints 1, not 2 } }; } void g() { extern int y; // y has external linkage; refers to global y defined elsewhere }
函数也可以声明为 extern
,但这没有效果。它通常用作读者的提示,这里声明的函数是在另一个翻译单元中定义的。例如:
void f(); // typically a forward declaration; f defined later in this TU
extern void g(); // typically not a forward declaration; g defined in another TU
在上面的代码中,如果 f
被改为 extern
而 g
改为 non-extern
,它根本不会影响程序的正确性或语义,但可能会使代码的读者感到困惑。