4

I have 2 C files below. From what i read i know that global variables' default storage class is extern. If i type it explicitly i am getting undefined variable error. What am i missing here? Does that mean when i omit extern keyword it becomes a definition but when i type it out its only a declaration?

file1.c

#include <stdio.h>
#include <stdlib.h>
extern void file2function();

int variable; // if i put extern i will get error, isnt it implicitly extern?

int main()
{
    variable = 1;
    printf("file1 %d\n",variable);
    file2function();
    return 0;
}

file2.c

#include <stdio.h>
#include <stdlib.h>

extern int variable;


void file2function(){
    variable = 2;
    printf("file2 %d\n",variable);
    return;
}
Sourav Ghosh
  • 133,132
  • 16
  • 183
  • 261
Ali Atıl
  • 121
  • 7
  • Yes, unless you also provide initialization (`extern int variable = 0;` ). See http://port70.net/~nsz/c/c11/n1570.html#6.9.2p4 . Note that C++ treats these differently. – Petr Skocik May 28 '17 at 18:11
  • Think about the fact that if you put extern in all declarations then where should the storage be allocated? You can't distinguish the only real definition. – Jack May 28 '17 at 18:12
  • So i have to omit extern or use initializer to point out where should storage be allocated? – Ali Atıl May 28 '17 at 18:14
  • For the omnibus presentation, see [How do I use `extern` to share variables between source files?](https://stackoverflow.com/questions/1433204/how-do-i-use-extern-to-share-variables-between-source-files) — but that is long. Simplistically, `extern int variable;` says "the variable `variable` is an `int` and is defined somewhere else", and you have to provide that definition somehow or the linking phase fails. It might be an `int variable = 27;` somewhere else in the same source file (at file scope), or it might be in another file which would have to be included in the linking command. – Jonathan Leffler May 28 '17 at 18:25

1 Answers1

6

You need to take a look at the difference between a definition and a declaration

That said, a variable declaration with extern storage is a hint to the compiler that the object is defined in some other place (or translation unit). It is not a definition on its' own.

You need to have a definition in one of the translation units used to generate the binary.

In your case, if you put extern in both the files, int variable becomes the declaration in both the cases. That's why, in linking stage, compiler cannot find a definition which was promised, so it screams.

On the other hand, if you remove the extern from one (only one) of the files, in that file, int variable; is a definition and the other translation unit refers to this definition, so, all good.

Sourav Ghosh
  • 133,132
  • 16
  • 183
  • 261
  • Thank you for the explanation. As you've said we have to give a hint to compiler. But for the auto keyword "auto int a;" statement is a definition but "extern int a;" it is only a decleration? Because "void function(){auto int a;printf("%d",a);return;}" doesnt give me any error.I hope i got it right? – Ali Atıl May 28 '17 at 18:26
  • @Splash: don't ever use `auto` in C code. Read up on storage classes, and definitions vs declarations (using the link Sourav gave you). – Jonathan Leffler May 28 '17 at 18:27
  • @Splash yes, `extern` and `auto` are two different storage class specifiers. – Sourav Ghosh May 28 '17 at 18:28
  • 1
    @JonathanLeffler Thanks for the comment sir. If I may ask, can I get a link where I can read more on _don't ever use `auto` in C code_ ? – Sourav Ghosh May 28 '17 at 18:29
  • 1
    My best link is [this](https://stackoverflow.com/questions/44230456/c-writing-extern-keyword-explicitly-for-global-variable#comment75471105_44230503) but you already read that — it's my comment from a couple of minutes ago. There's no need for `auto`, ever, in standard C from C99 onwards. In C89 you could write `auto x;` to mean `int x;` inside a function, but that was bad practice and more verbose too boot (by one letter!). I'll poke around and see if I can come up with something written by someone else. [C: A Reference Manual](http://careferencemanual.html) perhaps... – Jonathan Leffler May 28 '17 at 18:31