2

Why does the following piece of code work -

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

but this one doesn't -

main()
{
   extern int i;
   int i = 10;
   printf("%d", i);
}
Parzival
  • 585
  • 2
  • 12
  • 1
    in the first case, there are 2 `i` variables, one local and one global. you cannot use `extern` in the local scope. The main point is: what do you want to achieve. – Jean-François Fabre Aug 09 '18 at 07:30
  • Wrong mindset: the C language is defined by a specification (read [n1570](http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1570.pdf)) not by the behavior of your particular compiler on your computer. Be scared of [undefined behavior](https://en.wikipedia.org/wiki/Undefined_behavior) – Basile Starynkevitch Aug 09 '18 at 07:33
  • where is the undefined behaviour here? – Jean-François Fabre Aug 09 '18 at 08:04

3 Answers3

4

As already stated in comments, in the first fragment there are two distinct variables; scoping rules make that the local (inner) variable hides the outer one, but there are still two.

In the second fragment there is the temptative of declaring two times the same identifier, and the declarations collide each other.

  • In addition to this answer, I also want to advise to read this other StackOverflow question [How do I use extern...](https://stackoverflow.com/questions/1433204/how-do-i-use-extern-to-share-variables-between-source-files) to use it correctly. I have done a lot bug fixes where the `extern` was used incorrectly. That is seriously a "dangerous" keyword. – KarelG Aug 09 '18 at 07:45
1

Because extern means that the variable is defined elsewhere. You can define a variable from the global scope somewhere else (well, because it's global, so it's shared :) ), but you can't define a local variable elsewhere, because the function body is right here. If you could somehow split the function body in two between two files, declare this variable in one block, and then refer to it in another using extern, that would sort of make sense... But it's not possible, so extern inside a function body is meaningless.

UPD: I didn't notice that there are two variables in both cases, sorry. @linuxfan's answer applies better in this situation. I'll leave this answer here just in case it will be helpful for anyone (as additional details).

FreeNickname
  • 7,398
  • 2
  • 30
  • 60
  • I didn't want to take merit for someone else's comment. Beside: i didn't mention `extern` because I would like to use an extern variable locally scoped; it _can have_ sense. – linuxfan says Reinstate Monica Aug 09 '18 at 07:42
  • @linuxfan, I can remove that part of the update if you want. Just a personal opinion. As for `extern`, I still wouldn't agree. Because in that case it would exactly as though you're declaring a local variable, but with the `extern` keyword. It would cause confusion. – FreeNickname Aug 09 '18 at 08:35
  • No problem for anything. But for extern: it would not cause confusion, because extern is stated and you can read it. Think at a static local variable - do you accept it? It is a global one, but with local scoping. Why static yes, and extern no? – linuxfan says Reinstate Monica Aug 09 '18 at 10:00
  • @linuxfan, because `static` is not global in the same way `extern` is. `static` belongs to the function, it's kind of owned by it, and no one else can modify it (well, apart of cases when you explicitly pass a reference / pointer to it to the outside world). Semantically, it's not global, it's just persistent. `extern`, on the other hand is different. Well, that's probably a matter of perception :) – FreeNickname Aug 09 '18 at 21:48
1

In your first snippet. You're declaring that a global variable 'i' exists and has been declared elsewhere in some file that is included elsewhere in your project.

Other functions in the main file will be able to access that variable. The main function in the main file creates a local variable with the same name, and so will not be able to access the global 'i' variable.

The second snippet has two mistakes. 1) You are trying to declare a local extern variable - this is invalid. 2) You are trying to declare to variables in the same scope with the same name.

Spoonless
  • 561
  • 5
  • 14