当使用extern在文件之间共享常量时,为什么定义中需要extern

When sharing a const across files using extern, why is extern needed on the definition?

本文关键字:extern 为什么 定义 共享 文件 之间 常量      更新时间:2023-10-16

C++Primer第5版第60页讨论了如何在文件之间共享常量变量,如so

//file_1.cc
extern const int bufSize = fcn();
//file_1.h
extern const int bufSize;

何时定义bufSize?在file_1.cc上使用extern的目的是什么?我知道file_1.cc会定义它,但同一本书的第45页说,为变量提供初始值设定项会覆盖extern,那么为什么有必要在const的定义中使用extern呢?

根据标准,

如果名称空间作用域(3.3.6)是…的名称,则该名称具有内部链接。。。显式声明为constconstexpr但均未显式声明的非易失性变量extern之前未声明具有外部链接

因此,有一个特殊的规则,即当constconstexpr时,命名空间范围内的变量具有内部链接,即使它们本来具有外部链接。我不完全确定为什么存在这个规则,但我怀疑它是为了允许编译器内联const变量,因此根本不为它们分配任何存储空间。extern说明符显式重写了这一点,并使变量再次具有外部链接。

为变量提供初始值设定项会覆盖外部

现在有点不同了。默认情况下,变量的声明也是一个定义,但extern禁止这样做,因此您可以在不定义变量的情况下声明变量(即,因为其定义在另一个翻译单元中)。但是,如果您有一个初始值设定项,那么它会覆盖extern,并且声明再次成为一个定义。这实际上与上面关于内部和外部联系的规则无关。