Reputation: 610
In "C++ Primer, Fifth Edition" on page 95. Talking about constants. He said:
Sometimes we have a
const
variable that we want to share across multiple files but whose initializer is not a constant expression. In this case, we don’t want the compiler to generate a separate variable in each file. Instead, we want theconst
object to behave like other (nonconst
) variables. We want to define theconst
in one file, and declare it in the other files that use that object.To define a single instance of a
const
variable, we use the keywordextern
on both its definition and declaration(s):
// file_1.cc
defines and initializes aconst
that is accessible to other files.
extern const int bufSize = fcn();
// file_1.h
extern const int bufSize; // same bufSize as defined in file_1.cc
What I am not sure of is the last paragraph; I removed extern
from the definition of bufsize
but it is ok and is accessible from other files?!
const int bufSize = fcn(); // without keyword extern
Why he said we should add keyword extern
to both declarations and definition of bufsize
to be accessible from other files but extern
as I guess is enough in declarations?
Thank you for your help.
Upvotes: 1
Views: 139
Reputation: 62563
You are correct that extern
is not needed in cpp file.
First, you need to understand what is a declaration and a definition. Your bufSize
needs a declaration in every translation unit it is used, and a single definition inside your program. So let's look at what you have in the .h file:
extern const int bufSize;
This is a valid declaration of const int
variable. No confusion here.
Now you need a definition, which goes to a .cpp file, and you need to make sure that this exists in a single place in the whole program, otherwise you are breaking ODR - One Definition Rule. This is what you currently have:
extern const int bufSize = fcn();
This is a valid definition, since any declaration with extern storage class and initializer is a definition. However,
const int bufSize = fcn();
Also is a definition. And with preceeding declaration of extern
, this definition has an external linkage - which means, it can be accessed from other translation units (without that, const int bufSize
in namespace scope would have internal linkage).
Bottom line - extern
in the example doesn't affect the compiler behavior, but reminds whoever is reading the code that the variable has external linkage (as it is not immediately obvious from this line).
Further reading:
https://en.cppreference.com/w/cpp/language/definition
https://en.cppreference.com/w/cpp/language/storage_duration
Upvotes: 3