extern const,哪个是声明,哪个是前向声明

Extern const, which is the declaration and which is the forward declaration

假设我在 C++ 程序中有以下设置,在 global/namespace 范围内(在任何块之外):

情况一:

a.cpp

extern const int i=5;

b.cpp

extern const int i;

在我看来,编译器可以通过两种方式看到这一点。一是 i 的真正声明在 b.cpp 中,而 a.cpp 只有前向声明和初始化。 (因为我们知道对于特定的 extern 常量,不需要在声明时进行初始化)编译器可以生成的其他可能的可执行文件将包含 a.cpp 包含真实声明、初始化和 [=36 中的语句=] 被视为前向声明,只需要在那里帮助编译器知道我是什么。

编译器如何决定哪个文件负责实际声明,并因此决定与 i 关联的内存分配?如果使用具有有趣构造函数的类型而不是 int,这可能会产生表面上可观察到的效果。

如果有的话,这个问题的答案是如何改变的:

情况二:

a.cpp

extern const int i;
extern const int i=5;

b.cpp

extern const int i;

初始化器的存在立即将声明变成定义(除了少数例外,与我们的上下文无关)。这意味着

extern const int i = 5;

是您的i定义。它定义 i 并为其提供外部链接,即创建实际的 i 并使其对其他翻译单元可见("exports")。

同时,

extern const int i;
如果 i

是一个 non-defining 声明。它基本上说 i 在别处定义("imports")。

当您出于某种原因需要 C++ 中的全局 const 对象时,extern 的正确显式应用变得至关重要,因为在 C++ 中 const 对象具有 默认内部链接

请记住,为了使 const int 对象符合积分常量表达式 (ICE) 的条件,具有 ICE 初始值设定项的 const int 对象的声明必须可见。