1

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?

Matt
  • 49
  • 1
  • 8
  • 1
    Unlike C, a const in C++ defaults to internal linkage, in this case as if it had been declared static. extern is required to override this. – Neil Kirk Oct 10 '14 at 01:13
  • So extern will change the variable to external linkage, allowing it to be shared across files? – Matt Oct 10 '14 at 01:16
  • Yes. The alternative is to declare the const only in a header without extern. This is fine for a simple const (not a class) given a literal (eg `const int size = 5;`). But if a const in a header file is initialized from a function, the function will be called again for every source file that includes the header, which is inefficient. – Neil Kirk Oct 10 '14 at 01:18

1 Answers1

2

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.

Brian Bi
  • 111,498
  • 10
  • 176
  • 312