Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Order of `static` definition and `extern declaration` in a translation unit

Tags:

c

static

extern

I am unable to understand why this doesn't work.

extern int i;

int main()
{
  printf(" %d ", i);  
}

static int i =3;

Also, this doesn't work:

extern int i;

static int i =3;

int main()
{
  printf(" %d ", i);  
}

But if static variable is defined before the extern declaration it works:

static int i =3;

extern int i;

int main()
{
  printf(" %d ", i);  
}

As I understand from extern int itells that i is present somewhere else and here how it looks lik(int i)

But, somewhere else means:

1) Maybe, later point in the same translation unit as a global variable.

2) Maybe, in some other translational unit.

I was thinking that (1) would be valid even though static int i = 3 has restricted i's scope to the current translation unit where it is defined.

Isn't static int i =3 global( i mean atleast it is visible in the translation unit) here even though it has the restricted scope to its translation unit? Then why isn't compiler unable to find it?

When I compile the first two versions I get the following compile time error:

 error: static declaration of ‘i’ follows non-static declaration
 note: previous declaration of ‘i’ was here

I am unable to understand this error message. Also, why it is complaining it as a static declaration isn't it a definition also?

like image 953
Uchia Itachi Avatar asked Aug 09 '13 07:08

Uchia Itachi


1 Answers

C11 6.2.2 Linkages of identifiers Section 4

For an identifier declared with the storage-class specifier extern in a scope in which a prior declaration of that identifier is visible,31) if the prior declaration specifies internal or external linkage, the linkage of the identifier at the later declaration is the same as the linkage specified at the prior declaration. If no prior declaration is visible, or if the prior declaration specifies no linkage, then the identifier has external linkage.

So the second declaration will follow the first, back to your examples, the 1st and 2nd example i will have an extern storage-class. The compiler thinks that's an error.

While in the 3rd example, i will be static because static shows first. That should be no problem.

And, in the Section 7 of C11 6.2.2 Linkages of identifiers

If, within a translation unit, the same identifier appears with both internal and external linkage, the behavior is undefined.

So it's better not to declare the same variable with both static and extern in the same translation unit.

like image 171
Yu Hao Avatar answered Nov 01 '22 20:11

Yu Hao