Storage-class specifiers: static and extern

Hi there!

According to c++ standard, this code is correct:

1
2
static int b; // b has internal linkage
extern int b; // b still has internal linkage 


Why is that ? In my opinion, the first declaration has internal linkage, but the second one has external linkage because of the 'extern' word...
closed account (z05DSL3A)
The linkages implied by successive declarations for a given entity shall agree. That is, within a given scope, each declaration declaring the same object name or the same overloading of a function name shall imply the same linkage.

As b is declared as static first it has internal linkage any further declaration of b in the same scope has the same linkage as the first.
Grey Wolf wrote:
any further declaration of b in the same scope has the same linkage as the first.


Even if 'extern' word appears there ?
Basically, it ignores 'extern' and treats it as the first occurrence, 'static'. If extern int b; were declared first, then any subsequent declarations of 'b' would have external linkage, regardless of how they are declared.

Here, maybe this will help:
static int b; // b has internal linkage

extern int b; // b has external linkage

1
2
static int b; // b has internal linkage
extern int b; // b still has internal linkage 

1
2
extern int b; // b has external linkage
static int b; // b still has external linkage 

1
2
static int a; // a has internal linkage
extern int c; // c has external linkage 
Last edited on
RyanCaywood wrote:
regardless of how they are declared.


It's sorry to say but you're wrong. Your second example:

1
2
extern int b; //b has external linkage
static int b; //b still has external linkage 


is incorrect because the linkages don't agree (second declaration has internal linkage).
is incorrect because the linkages don't agree (second declaration has internal linkage).


I thought the point of that was that they *don't* agree but the first one takes priority. Did you read the entire topic?
Maybe you're right...
To be honest I'm not completely sure on this but here is how I think it works:

1
2
3
4
5
6
7
int i; // extern linkage

static j; // internal linkage

// declare to compiler that there is a symbol
// with extern linkage elsewhere.
extern k; // Note: this does create k, just adds it to the symbol table 


So the static keyword directs the compiler to issue assembler to create a variable with internal linkage. Not using the static keyword causes the compiler to export the symbol of the variable it creates.

However the extern keyword does not actually create anything, but tells the compiler that something was created elsewhere that does have external linkage. That means it must have been defined without the static keyword.

So saying 'static' makes an item internal. No keyword makes an item external. The extern keyword is simply a hopeful promise to the compiler that an externally linkable definition exists somewhere else.
closed account (z05DSL3A)
There are many rules that define if a name has external linkage, internal linkage, or no linkage. It depends on storage class, scope, translational unit, etc. Specifically in this thread we are talking about redefining a name within the same scope, in this case the linkage of any redeclaration is the same as the linkage of the first declaration.

Edit:
The standard takes about two pages for the basic overview of the rules.
Last edited on
Topic archived. No new replies allowed.