The procedure for determining `static` and` extern declaration` in translation units

I canโ€™t understand why this is not working.

extern int i; int main() { printf(" %d ", i); } static int i =3; 

Also, this does not work:

 extern int i; static int i =3; int main() { printf(" %d ", i); } 

But if the 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 i says that i present somewhere else , and here is what it looks like ( int i )

But somewhere else means:

1) Perhaps later, specify in the translation block the same as global variable .

2) Perhaps in some translational unit other .

I thought that (1) would be valid even if static int i = 3 limited area i current translation unit where it is defined.

Not static int i =3 global (I mean, at least it can be seen in the translation block), although it has a limited scope for its translation unit? Then why can't the compiler find it?

When compiling 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 can not understand this error message. Also, why does he complain about it as a static declaration and not a definition ?

+6
source share
3 answers

C11 6.2.2 Identifier associations Section 4

For an identifier declared using the storage class specifier extern in the area in which the preliminary declaration of this identifier is visible, 31) if the previous declaration indicates an internal or external relationship, the relationship of the identifier with a later declaration matches the binding specified in the previous declaration. If no preliminary announcement is displayed or if no binding is specified in the previous announcement, then the identifier has an external binding.

So, the second declaration will follow the first, back to your examples, the first and second examples i will have an extern storage class. The compiler thinks the error.

In the third example, i will be static because static displayed first. This should not be a problem.

And in section 7 of section C11 6.2.2 Identifier associations

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

Therefore, it is better not to declare the same variable with static and extern in the same translation unit.

+6
source

Well, the variable is extern or static . Remember that static at the global level limits its visibility to the current translation unit only, while extern dictates that it is visible on different translation units.

+2
source

It makes no sense to declare something as static and again as extern . This behavior is undefined, so do not do this.

0
source

Source: https://habr.com/ru/post/951378/


All Articles