2

Can you please someone explain me the flow of below problem,

#include <stdio.h>

int main(){
   extern int a;
   printf("%d\n",a);
   return 0;
}

int a = 20;

and the output is 20. I am not sure where is the variable a getting defined and where is it getting declared?

Jabberwocky
  • 48,281
  • 17
  • 65
  • 115
nullbyte91
  • 161
  • 2
  • 9
  • Related: https://stackoverflow.com/questions/496448/how-to-correctly-use-the-extern-keyword-in-c – Azeem Jun 26 '17 at 03:47

5 Answers5

2

The variable a is declared and defined as a global variable in the line:

int a = 20;

The extern line just tells the main() function scope that a is defined in another place.

In this case, the use of extern is not really necessary. You could just declare and define a before the main() function, and then main() would be familiar with it.

Usually, you would use extern when you want to use a variable or a function that was defined in another source file (and not just later in the same source file).

SHG
  • 2,516
  • 1
  • 14
  • 20
2

extern is syntactically a "storage class" keyword. But there is no such storage class. C has "static storage", "dynamic storage (malloc, etc) and "automatic storage" (local variables, usually represented using a stack).

If an identifier is declared extern inside a block scope, it means that the declaration refers to an external definition. If the entity being declared is an object, then it has static storage, simply because external objects have static storage. It can be a function too; functions aren't said to have storage.

In C, there is a concept called "linkage". Objects declared outside of any function at file scope, and functions, can have "external" or "internal" linkage.

If we have extern in a block scope, as you have in the example program, there can be a prior declaration of the same name at file scope, or in a nested scope, like this:

static int x;

/* ... */

  {
    extern int x;
  }

Here, the inner x refers to the outer x, and, in spite of being "extern", it has internal linkage because of the "static".

In a nutshell, extern usually means "refer to the earlier declaration, and if there isn't one, declare this as an identifier with external linkage".

The word "external" refers to two separate concepts: the aforementioned "external linkage" and also to the meaning "outside of any function", as in "external declaration". Confusingly, "external declarations", like the static int x above, can have "internal linkage"!

In your program, things are correct because the block scope extern declaration of a and the later int a = 20, which are in separate scopes, happen to independently agree with each other.

The int a = 20; is an external declaration, which is also an external definition (because of the initializer). Since in that scope, no prior declaration of a is visible, it gets external linkage.

So, where is a defined? It is defined as an object with external linkage, in the entire translation unit as a whole. That translation unit is what defines a. a is declared in every place of the program where a declaration appears; and its definition is also a declaration. It is declared in main and also in the last line of the translation unit's source code.

A "declaration" is syntax which makes a name known in some scope. It's a concept that is active during the translation of a program. A "definition" is the fact that some object or function is provided in some translation unit. Translated units still provide definitions, but need not retain information about declarations. (Which is why when we make libraries, we provide header files with declarations in them!)

From the point of view of your main function, that function doesn't "care" where a is defined. It has declared a in such a way that if a is used, then an external definition of a, with external linkage, must exist. That definition could come from anywhere: it could be in the same translation unit, or in another translation unit.

Kaz
  • 55,781
  • 9
  • 100
  • 149
2

The C programming language has been designed to be one-pass, so that the compiler could process each line only once from top to bottom. So considering your program:

#include <stdio.h>

int main(){
   extern int a;
   printf("%d\n",a);
   return 0;
}

int a = 20;

The identifier a is declared twice, and defined once.

Before the 4th line extern int a;, the compiler doesn't know anything about the identifier a. The declaration extern int a; has the block scope within the function main, and it declares the identifier a as an int and that its storage duration is static and linkage is external. So the compiler can write code that access a global identifier by name a as an int variable that could be defined in another module (external linkage). This is what the compiler does on line 5 when it is used in printf.

Finally at line 9, int a = 20; is another declaration and definition. This declares and defines a as a int with static storage duration, and external linkage.

If you'd put the int a = 20; before the main, the declaration extern int a; would be useless, because it doesn't add anything. I tend to put my main and other depending functions last in my source code, so that minimal amount of extra declarations are needed.

  • In the C standard, the terms used for the storage duration are 'static duration' vs 'thread duration', 'automatic duration' or 'allocated duration'. Similarly, it is 'internal linkage' vs 'external linkage' vs 'no linkage' for name visibility. The storage class on `a` is not `static`, but its storage duration is static. 'Tis tricky — I'm probably guilty of sloppiness on occasion, too. – Jonathan Leffler Jun 26 '17 at 06:32
0

When ever you declare a variable as extern then It means that Variable is declared as global and you cannot initialize the variable there.Because no memory is allocated for that variable It is just declared as a Variable you can define it some where in your code.

Let us take an example ..consider the code

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

here you get an error that int 'i' is not defined

therefore you need to write it as:

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

In case of your code: This is declaration

extern int a;

This is definition:

int a = 20;
Madhusudan chowdary
  • 543
  • 1
  • 12
  • 20
  • **When ever you declare a variable as extern then It means that Variable is declared as global**. Can you explain this ? – GAURANG VYAS Jun 26 '17 at 05:03
  • I think you mean to say that the a variable declared as `extern` is declared global in some other file, but it can be local to function in the files where we provide its declaration. – GAURANG VYAS Jun 26 '17 at 05:15
  • A variable declared as `extern` is a global. You can give definition to it at any where in your program even out side of your main function. – Madhusudan chowdary Jun 26 '17 at 06:07
  • If you need such kind of stuff .You can go through the book called **Test your C skills** by yeshwanth kanethkar. [link](http://www.amazon.in/Test-Your-Skills-Yashavant-Kanetkar/dp/8183331181) or you can get free online pdf version – Madhusudan chowdary Jun 26 '17 at 06:11
0

The storage class extern specifies storage duration and linkage of the object the identifier refers to:

The storage duration is set to static, which means the variable is alive for the whole time the program runs. As you declare that variable inside a function scope, this matters in your example, because in function scope, the default storage duration would be automatic.

The linkage is set to external, this just means different translation units of the same program can share the object. It has the side effect that a definition in another (file) scope is acceptable, as shown in your example. This is a logical consequence of the shared nature, you would typically declare a variable with external linkage in all translation units using it, but define it only in one.