This question already has answers here:
How do I use extern to share variables between source files?
(19 answers)
Closed 9 years ago.
i am confused in the use of extern keyword in C. when it is used with a variable, then it means the declaration of variable. I declare the variable tmp outside the main() function and define it in a separate block in main but when i print the value in subsequent block i got an error "UNRESOLVED EXTERNAL LINK". I am confused please give me detailed explanation.
#include <stdio.h>
extern int tmp ;
int main()
{
{
int tmp = 50;
}
{
printf("%d",tmp);
}
return 0;
}
No; extern int tmp; means "somewhere else there is a definition of the variable tmp"; this is a declaration — you can reference tmp but it is not defined. Further, when you write extern int tmp; outside a function, it means that the variable will be defined outside a function — it is a global variable which may be defined elsewhere in the current source file or in another source file. (The rules for extern int tmp; written inside a function are moderately complex; let's not go there now!)
Your local variable int tmp = 50; in the function is unrelated to the global variable tmp declared outside. The local variable hides the global variable inside the braces. (The local variable is also unused.) The printf() statement, though, references the global variable; the local variable is not in scope for the printf().
Because you do not define the global variable (for example, by adding int tmp = -2; at the bottom of the file), your program fails to link and will continue to do so until you either define the variable in this source file or link in another source file where the variable is defined.
This line :
extern int tmp ;
says look for the tmp variable definition elsewhere , which means look for the variable definition in other translation unit in the entire program.
when you define int tmp in main it is local to that function, i.e it doesn't have any external linkage.
Disclaimer- There are seriously many posts on SO regarding this like the one with link provided in the comments above . No, matter how much I add to this it will end up being a repetition. however , you have a good answer below by Jonathan leffler too.
Extern is redeclaration
, so it doesn't crate variable, but only tells compiler that real declaration is somewhere else.
You can use it in one source file to refer to variable declaration in another file, or in the same file to express that you use previously declared global variable.
So when you declare global variable
int a=5;
and use in function in the same source file, you can add extern int a; in the body of a function to clearly tell that it uses global variable but declaration is not here.
type func(arguments){
extern int a;
.
.
.
And when int a=5 is in another source file you place
extern int a;
in source file you actually want to use global variable a declared in previous source file.
This is about linkage. When you declare a variable extern you give it external linking, saying it's defined with global linkage somewhere else.
In your function you're defining a variable called tmp, but it doesn't have global linkage, it's a local variable. You'd have to define it outside of any function to give it global linkage.
There's also static linkage, which means a variable is global but only to the current compilation unit (source file).
Using the extern keyword you only declare the symbol tmp. Which means the symbols is defined somewhere else and will be resolved at link time.
So if you do not provide a compiled object defining the symbol, the linker gives you some kind of "unresolved symbol" error.
See the following question for more details on Declaration or Definition in C
Related
This question already has answers here:
How do I use extern to share variables between source files?
(19 answers)
Closed 3 years ago.
There is a code snippet as below,
int var1;
extern int var2;
It is a multiple choice.
The answer is, First statement declares and defines var1, but second statement only declares var2.
But I think it is supposed to be "Both statements only declare variables, don’t define them."
Which one is correct?
This might help. source
Declaration of a variable is for informing to the compiler the
following information: name of the variable, type of value it holds
and the initial value if any it takes. i.e., declaration gives details
about the properties of a variable. Whereas, Definition of a variable
says where the variable gets stored. i.e., memory for the variable is
allocated during the definition of the variable.
In C language definition and declaration for a variable takes place at
the same time. i.e. there is no difference between declaration and
definition. For example, consider the following declaration
int a;
Here, the information such as the variable name: a, and data type:
int, which is sent to the compiler which will be stored in the data
structure known as symbol table. Along with this, a memory of size 2
bytes(depending upon the type of compiler) will be allocated.
Suppose, if we want to only declare variables and not to define it
i.e. we do not want to allocate memory, then the following declaration
can be used
extern int a;
In this example, only the information about the variable is sent and
no memory allocation is done. The above information tells the compiler
that the variable a is declared now while memory for it will be
defined later in the same file or in different file.
The answer depends on several factors.
If these declarations
int var1;
extern int var2;
are block scope declarations then the first declaration is also a definition and the second declaration is just a declaration without a definition. The variable var1 is not initialized that is it has an indeterminate value.
If these declarations are declarations of the file scope then whether the first declaration is a definition is defined by whether the declaration has an external definition.
If the declaration does not have an external definition then this declaration named as tentative definition is a definition and have an implicit initializer equal to 0.
As for the second declaration then again whether it is a definition depends on whether there is an external definition or not. If there is no external definition then the linker can either create the definition or issue an error.
In C a declaration with the file scope is also a definition when either it has an initializer or it is a tentative definition without an external definition.
Actually, the extern keyword extends the visibility of the C variables and C functions.
Declaring vs Defining a variable?
Declaration of a variable/function simply declares that the variable/function exists somewhere in the program but the memory is not allocated for them.
Snippet 1:
extern int var;
int main(void)
{
var = 10;
return 0;
}
Snippet 1 throws an error in compilation. Because var is declared but not defined anywhere. Essentially, the var isn’t allocated any memory. And the program is trying to change the value to 10 of a variable that doesn’t exist at all.
Snippet 2:
#include "somefile.h"
extern int var;
int main(void)
{
var = 10;
return 0;
}
Supposing that "somefile.h" has the definition of var. Snippet 2 will be compiled successfully.
This question already has answers here:
What is the difference between a definition and a declaration?
(27 answers)
Closed 5 years ago.
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?
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).
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.
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.
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;
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.
#include <stdio.h>
int main()
{
extern int a;
extern int a;
int a = 10;
return 0;
}
what is the problem with this code? Since multiple declaration is allowed in c what is the problem with this code
The problem with the code is that the compiler is first informed that a is a global variable (due to the extern keyword); and then a is defined as a local 'automatic' variable. Hence there is a conflict in the defined scope of a
As an alternative to automatic variables, it is possible to define variables that are external to all functions, that is, variables that can be accessed by name by any function. (This mechanism is rather like Fortran COMMON or Pascal variables declared in the outermost block.) Because external variables are globally accessible, they can be used instead of argument lists to communicate data between functions. Furthermore, because external variables remain in existence permanently, rather than appearing and disappearing as functions are called and exited, they retain their values even after the functions that set them have returned. —The C Programming Language
An external variable must be defined, exactly once, outside of any function; this sets aside storage for it. The variable must also be declared in each function that wants to access it; this states the type of the variable. The declaration may be an explicit extern statement or may be implicit from context. ... You should note that we are using the words definition and declaration carefully when we refer to external variables in this section. Definition refers to the place where the variable is created or assigned storage; declaration refers to places where the nature of the variable is stated but no storage is allocated. —The C Programming Language
From your question I observe that you are visualizing your program something like this
#include <stdio.h>
int main()
{
extern int a; //declaration
extern int a; //declaration
int a = 10; //declaration + definiton
return 0;
}
With above understanding of extern keyword. Your question is obvious.
Let us understand use extern of keyword thoroughly.
Extern variable declaration is a promise to the compiler that there would be a definition of a global variable some place else. Read This. In other words extern keyword tell the compiler that forget about this variable at the moment and left it to linker to link it with its definition. That is extern variables are actually linked to its definition by linker. Moreover Local variables have no linkage at all. So while searching for its definition compiler found a definition without linkage. Thats the error.
As a rule of thumb just remember when you declare any variable as extern inside any function then you can only define it outside of that function.(However there is no use of it).
I have a few doubts regarding the use of extern keyword with variables in C. I did go through the links related to this question. However, there are still a few things that I didn't gather very well
#include<stdio.h>
main( )
{
extern int i;
printf ( "\n%d ",i) ) ;
}
int i = 31 ;
In the above code, how does I get printed before its definition statement?
Now in the following code:
#include<stdio.h>
int x = 21 ;
main( )
{extern int i;
i=20;
printf ( "\n%d ", i ) ;
}
Isn't the statement "i=20;" a definition statement? I get an error for this. Is it because i'm trying to change the variable that is defined in some other source file? If this is the case how is the statement "int i=31;" in the top most code snippet right to use?
Also, I read, "int i;" is a definition. I don't really follow how.
In your first program, the print statement is printing the value of i based on the extern int i declaration. This is similar to calling a function based on its prototype declaration without seeing its definition. The compiler generates code to retrieve the value in the global variable named i. The symbol is resolved to the correct variable and address at link time.
In your second program, no definition for i is provided, only the extern int i declaration, and the attempt to set its value with i = 20. At link time this fails, since there is no definition, and so the attempt to resolve the reference to the global variable fails. Changing i = 20 to int i = 20 instead creates a local variable named i within the scope of the function main(), and is no longer referencing the globally declared extern int i.
When int i; is used at global scope, it is treated as a declaration and may be treated as a kind of definition. A global variable declared with an initializer, like:
int i = 20;
is always treated as a definition. Only one definition of this type is allowed, even if each is using the same initializer value. However,
int i;
is treated like a declaration. If more than one of these declarations appear, they are all treated as declarations of the same variable. At the same time, if no declaration with an initializer is present, this variable is implicitly defined with an initializer of 0, and the linker will be able to resolve references to it.
Declaration of a variable/function simply declares that the variable/function exists somewhere in the program but the memory is not allocated for them.
Coming to the definition, when we define a variable/function, apart from the role of declaration, it also allocates memory for that variable/function.
So in the 1st program, int i = 31 outside the main() defines the variable i. This variable is then merely declared as an extern variable inside the main(). Hence the program works.
In the 2nd program, without defining the variable i elsewhere, it is directly declared as an extern variable. Hence it gives an error.
In the second program you haven't defined the variable anywhere , not outside the main and instead you have defined it inside main so you are getting that error.
But in the first program you are defining the variable once and that is outside the main so you don't get that error.Program looks outside the main and find its definition.
int i; is a variable definition declaration both for AUTO variables (i.e inside main or any function ) but not for the external variables for extern variables you have to declare it like :
extern int i;
and then define outside main like this :
int i;
The idea behind extern is that you tell the compiler you're going to use a variable that was already defined outside the scope of where it is used.
It doesn't make much sense in your second case as there i is defined as a local variable.
If you were to define it as a global, like you do in the first case, it would be fine.
If I can demonstrate the use of extern with a very simple (contrived) case:
main.c:
#include <stdio.h>
extern int a; /* we tell the compiler that a will come from outside the scope of where it is used */
int main()
{
printf("%d\n", a);
return 0;
}
source.c:
int a = 3; /* we define a here */
You then compile both .c files like this:
$ gcc main.c source.c
This outputs 3.
You might also want to have a read at this article.
I am trying to understand this code:
#include<stdio.h>
int main()
{
extern int a;
printf("%d\n", a);
return 0;
}
int a=20;
When I run it, the value of a is 20. Yet this should be impossible, since the global variable a is defined at the bottom.
An extern declaration can only be used with variables that are global. It tells the compiler that the global variable is defined elsewhere, and asks the linker to figure it out.
In your code, extern int a refers to the a defined at the bottom of your example. It could have been equally well defined in a different translation unit.
As others have pointed out, the initialization of a takes place before main() is entered.
Not a problem. By declaring the variable as extern you are promising the linker it is defined else where part of current or other source files at global scope.
Initialization of global variables occurs before main() is called.
So even if the initialization a = 20 is located beneath the implementation of main(), it's always executed first, so it can be used at program start (assuming you fittingly declared the variable in scopes where it's to be used using extern int a).