当使用extern在文件之间共享一个const时,为什么extern需要定义? [英] When sharing a const across files using extern, why is extern needed on the definition?

查看:398
本文介绍了当使用extern在文件之间共享一个const时,为什么extern需要定义?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

  // 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)具有内部链接,如果它的名称...一个非易失性变量,显式声明 const constexpr 并没有明确声明
extern 也没有声明为外部链接


所以有一个特殊的规则,当 const constexpr 即使它们将具有外部连接。我不完全确定为什么这个规则存在,但我怀疑它是允许编译器内联 const 变量,因此不为它们分配任何存储。 extern 说明符明确覆盖此变量,并使变量再次具有外部链接。


提供一个变量的初始化器覆盖extern


现在这有点不同。默认情况下,一个变量的声明也是一个定义,但是 extern 禁止这样做,所以你可以声明一个变量而不定义它(即因为它的定义在另一个翻译单元)。但是如果你有一个初始化器,它会覆盖 extern ,声明再次成为一个定义。这与上面关于内部和外部链接的规则并不真正相关。


Page 60 of C++ Primer 5th edition talks about sharing const variables across files like so

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

//file_1.h
extern const int bufSize;

When would bufSize be defined and what is the purpose of extern on file_1.cc? I understand that file_1.cc would define it, but Page 45 of the same book says that providing an initializer for a variable overrides the extern, so why is it necessary to have extern on the const's definition?

解决方案

According to the standard,

A name having namespace scope (3.3.6) has internal linkage if it is the name of ... a non-volatile variable that is explicitly declared const or constexpr and neither explicitly declared extern nor previously declared to have external linkage

So there is a special rule that variables at namespace scope have internal linkage when const or constexpr even if they would otherwise have external linkage. I'm not entirely sure why this rule exists but I suspect it's to allow the compiler to inline const variables and hence not allocate any storage for them at all. The extern specifier explicitly overrides this and makes the variable have external linkage again.

providing an initializer for a variable overrides the extern

Now this is a bit different. By default a declaration of a variable is also a definition, but extern suppresses this so you can declare a variable without defining it (i.e. because its definition is in another translation unit). But if you have an initializer then it overrides the extern and the declaration once again becomes a definition. This isn't really related to the rules about internal and external linkage above.

这篇关于当使用extern在文件之间共享一个const时,为什么extern需要定义?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆