Why it is not needed to decorate a “const char *” with “extern” when sharing it cross multiple files
Question
While reading C++ books, I learned that to share a const variable/object cross multiple files, we need to define the const variable once in one of the files, and declare it in each source file where it is used. For example,
In file1.cpp, we define a const int variable globally like
extern const int ca = 100;
In file2.cpp where we use it, we declare this variable like
extern const int ca;
The above convention makes perfect sense for me. However, when coming to a const char pointer, we don't need to define it using extern, and it can be shared cross multiple files very well. Why does such a thing happen? For example,
In file1.cpp, we define a const char pointer variable globally like
const char *cstr = "hello";
In file2.cpp where we use it, we declare this variable like
extern const char *cstr;
To make my question more specific, why can cstr be used in file2.cpp even though it is not decorated with "extern" in file1.cpp?
Many thanks
Solution
The issue is one of linkage. When you define a variable at namespace scope, and there is no previous declaration which establishes linkage, the linkage external if the object is not const, internal if it is. So when you write:
int const ca = 100;
in a source file, the linkage will be internal, and the entity
(the variable) ca
refers to will be unique to that translation
unit. If you'd written:
int ca = 100;
the linkage would be external, so an
extern int ca;
in another translation unit would refer to the same variable.
And of course, when you write:
char const* cstr = "hello";
you are defining a pointer, which isn't const (although it points to const).
Of course, normally, you'd declare the variables in a header,
with extern
, so there would be a previous declaration when you
define the variables, and it is the first declaration which
establishes the linkage.
OTHER TIPS
extern is used to make it explicit that the statement "extern const char *cstr;" is a declaration and not a definition, cstr is defined somewhere else. If you did "const char *cstr;" the compiler would interpret that as a definition and you'd end up with 2 cstr variables.
If you apply extern on "const char *cstr = "hello";" I guess the compiler ignores it because the initialization means you actually are defining the variable.