Alex24
Alex24

Reputation: 610

Should I add keyword `extern` to the definition of a constant to share among source files?

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 the const object to behave like other (non const) variables. We want to define the const 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 keyword extern on both its definition and declaration(s):

// file_1.cc defines and initializes a const 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

Answers (1)

SergeyA
SergeyA

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

Related Questions