4

I'm trying to figure out what happens if in some program we'll have like that:

extern int x;

void foo(){...}
void bar(){...}

void main(){
foo();
bar();
}
int x=0;

So what is suppose to happen?Why is it allowed to have two such variables with the same name?are they different?

ChikChak
  • 936
  • 19
  • 44
  • 2
    Try compiling: `int x; int x; int x = 3; extern int x;`. Even with very fussy options set for GCC, it compiles. Move the `extern` line to the top and `clang -Weverything` accepts it. The first two `int x;` are tentative definitions. The `int x = 3;` is a non-tentative (definitive?) definition. You couldn't repeat that, or use a different initializer. If there was no definitive definition by the end of the file, the `int x;` would be converted into one. – Jonathan Leffler Feb 08 '17 at 22:17
  • A variable declared at file scope with no storage-class specifier has the same storage class and linkage as one explictly declared `extern`. That is, there's no distinction between the kind of variables you're calling "extern" and the kind you're calling "global". The presence or absence of `extern` can make a difference in other ways, though. – John Bollinger Feb 08 '17 at 22:19

3 Answers3

7

They are not "two" variables. They are the same.

extern int x;

is a declaration of x.

and

int x=0;

provides the definition for x. This is perfectly fine and valid.


You can have multiple declarations like:

extern int x;
extern int x;

too and it'll compile as well.

Note when you are providing the multiple declarations for the same identifier, the rules are somewhat complex. See: 6.2.2 Linkages of identifiers for details. See static declaration of m follows non-static declaration for an example.

Community
  • 1
  • 1
P.P
  • 117,907
  • 20
  • 175
  • 238
3

Perfectly fine. This

extern int x;

only declares the variable x of type int and extern explictly says, that it will be defined at an another location.

In your case , a few lines below

int x = 0;

Here is a link for more info on extern -> http://en.cppreference.com/w/cpp/language/storage_duration

The extern specifier is only allowed in the declarations of variables and functions (except class members or function parameters). It specifies external linkage, and does not technically affect storage duration, but it cannot be used in a definition of an automatic storage duration object, so all extern objects have static or thread durations. In addition, a variable declaration that uses extern and has no initializer is not a definition.

Alex
  • 779
  • 7
  • 15
2

"extern" means:
"this variable will come from some other place. It is not being declared here; this statement just provides notice that it is a valid name."

So in essence this code is:

extern int x;
// This is a valid name, but the variable will be defined "externally", eg, somewhere else.

[...] 

int x=0;
// OH!  Here is where the definition is.  Now we know where that "extern" variable came from.
// And we know that it starts with value 0.

It is somewhat unusual for and extern and definition to appear in the same file.

More typically, the definition is in one .C file, and the extern is in a different .C that will get linked together during the build process.

abelenky
  • 63,815
  • 23
  • 109
  • 159