user1371943
user1371943

Reputation:

External variable declaration and definition

a)The definition of an external variable is same as that of a local variable,ie, int i=2; (only outside all functions). But why is extern int i=2; too working as the definition? Isn't extern used only in variable declaration in other files?

b)file 1

  #include<stdio.h>
  int i=3;
  int main()
  {
      printf("%d",i);
      fn();
  }

file2

  int i;  //  although the declaration should be: extern int i; So, why is this working?
  void fn()
  {
      printf("%d",i);
  }

OUTPUT: 3 in both cases

Upvotes: 1

Views: 5776

Answers (2)

Christoph
Christoph

Reputation: 169563

For historical reasons, the rules for determination of linkage and when a declaration provides a definition are a bit of a mess.

For your particular example, at file scope

extern int i = 2;

and

int i = 2;

are equivalent external definitions, ie extern is optional if you provide an initializer.

However, if you do not provide an initializer, extern is not optional:

int i;

is a tentative definition with external linkage, which becomes an external definition equivalent to

int i = 0;

if the translation unit doesn't contain another definition with explicit initializer.

This is different from

extern int i;

which is never a definition. If there already is another declaration of the same identifier visible, then the variable will get its linkage from that; if this is the first declaration, the variable will have external linkage.

This means that in your second example, both file1 and file2 provide an external definition of i, which is undefined behaviour, and the linker is free to choose the definition it likes best (it may also try to make demons fly out of your nose). There's a common extension to C (see C99 Annex J.5.11 and this question) which makes this particular case well-defined.

Upvotes: 5

David Heffernan
David Heffernan

Reputation: 612934

In C, an extern with an initialization results in a variable being allocated. That is the declaration will be considered a defining declaration. This is in contrast with the more common use of extern.

The C standard says:

6.9.2 External object definitions

.....

If the declaration of an identifier for an object has file scope and an initializer, the declaration is an external definition for the identifier.

As for the second part of your question, your declaration int i at file scope has external linkage. If you want to give it internal linkage you need to declare it static int i. The C standard says:

6.2.2 Linkages of identifiers

......

If the declaration of an identifier for an object has file scope and no storage-class specifier, its linkage is external.

Upvotes: 1

Related Questions