According to C++ Primer, we can provide an initializer on a variable defined as extern, but doing so overrides the extern. An extern that has an initializer is a definition:
extern double pi = 3.1416; // definition
It is also stated in the book that providing an initializer on an extern inside a function is an error. These two statements together are a little confusing in my opinion and they give rise to the following questions in my mind:
If providing an initializer on an extern outside any function can override the extern, why can providing it on an extern inside a function not?
I also don't understand why someone would want to both obtain a declaration adding the extern keyword and provide an initializer. Is it not the same as defining a variable and providing an initializer on it? If it is not, why? Is the answer the reason why we cannot provide an initializer on an extern inside a function?
According to C++ Primer, we can provide an initializer on a variable defined as
extern
, but doing so overrides theextern
.
Only partially.
Providing an initializer forces the declaration to be a definition (except in the case of some static members of classes). It thus partially counteracts the effect of extern
, which usually suppresses definition. However, extern
can have other effects, and the initializer doesn't nullify those.
It is also stated in the book that providing an initializer on an extern inside a function is an error.
Yes. At block scope, extern
is used to force a declaration to have external or internal linkage (rather than declaring a local variable). However, the language prohibits defining such a variable in a local scope. You can only declare it there, and provide a matching definition at namespace scope. If you provide an initializer, then you're trying to define the variable there, which is not allowed.
If providing an initializer on an extern outside any function can override the extern, why can providing it on an extern inside a function not?
As I explained, this premise is false. The initializer, in both cases, makes the declaration into a definition. In both cases, it does not override the fact that extern
affects the linkage of the entity being declared.
I also don't understand why someone would want to both obtain a declaration adding the
extern
keyword and provide an initializer. Is it not the same as defining a variable and providing an initializer on it? If it is not, why?
When we use extern
together with an initializer, it is usually because we are trying to define a const
object with external linkage. See below:
// At global scope:
const int c1 = 42; // definition with internal linkage
extern const int c2; // declaration with external linkage
extern const int c3 = 42; // definition with external linkage