In c, it seems to me that everything written outside of a function is already 'extern'.
When, then, exactly do you have to specify a variable as extern?
Does it have to do with definition vs declaration?
Also, is declaring a variable with extern necessary in order to access a variable defined in another file already?
the extern extends the visibility to the whole program, by externing a variable we can use the variables anywhere in the program provided we know the declaration of them and the variable is defined somewhere.
Declarations of variables at file scope (Not in other files ) are external by default.
In c, it seems to me that everything written outside of a function is
already 'extern'. When, then, exactly do you have to specify a
variable as extern?
this is most probably true for c functions
By default, the declaration and definition of a C function have “extern” prepended with them
For example have one file named file1.c and declared function lilke
int my_function();
There’s an extern present in the beginning which is hidden and the compiler treats it as below.
extern int my_function();
Therefore whenever we define a C function, an extern is present there in the beginning of the function definition.
For C variables
While defining a function, we can prepend it with extern without any issues. But it is not the case with C variables.
If we put the presence of extern in variable as default then the memory for them will not be allocated ever, they will be declared only. Therefore, we put extern explicitly for C variables when we want to declare them without defining them. `
Here is how you would use extern variables.
I have a UART.c:
#include<stdio.h>
#include<string.h>
#include<UART.h>
int UART_Rcv(unsigned char* Rx_Str[], unsigned int len);
int status;
int UART_Rcv(unsigned char* Rx_Str[], unsigned int len)
{
//Some code for implementation of UART receive.
//set status value and return it, May be (SUCCESS or FAILURE?)
return status;
}
Now I have a UART.h
//header guard
#ifndef __UART_H
#define __UART_H
//Some UART related macros
extern int status;
extern int UART_Rcv(unsigned char* Rx_Str[], unsigned int len);
//other externs if any
#endif
Now I have a main.c which is going to use the function and variable declared in UART.c
#include<stdio.h>
#include<string.h>
#include<UART.h>
#define WIMP_OUT_N_GO_HOME (0)
int main(void)
{
unsigned char Received_String[30];
//Some code and may be initialization of UART?
//Flush the Received_String before using it
UART_Rcv(Received_String, 10);
//Some code
return WIMP_OUT_N_GO_HOME;
}
When a variable is defined, the compiler allocates memory for that variable and possibly also initializes its contents to some value. When a variable is declared, the compiler requires that the variable be defined elsewhere. So By externing your UART_Rcv() function and the status variable, you hinted your compiler that those are defined outside of the functional block, or may be in a different source, like we did here. the definitions for those will be found at the linker time.
An external variable must be defined, exactly once, outside of any function
Related
This answer confused me.
If we have two lines in same .c file:
extern int c;
int c;
How is the first line of code a declaration and second a definition?
Aren't both declarations?
How these two lines differ?
The extern keyword is what makes the first line a declaration. It say "this variable exists somewhere". A line like that can appear in a header file.
The second line is a definition because the extern keyword is not present. If you were to have this line in a header file, two source files that include that header will both define that variable and linking those two files will result in a variable redefinition error.
When the program you're writing consists of multiple source files linked together, where some of the variables defined, for example, in source file file1.c need to be referenced in other source files, so this is the reason why using extern.
About your question how these lines differ:
extern int c;
int c;
A variable is defined when the compiler allocates the storage for the
variable while
A variable is declared when the compiler is informed that a variable
exists (and this is its type); it does not allocate the storage for
the variable at that point.
so only int c; is defined while extern int c; is declared .
A definition creates space for a variable:
int c;
Wherever you put this line, either local, global, this says that a new variable c of type int shall come to life.
extern int c;
A declaration says that there is somewhere else some variable c of type int. By using extern, you say that c is defined somewhere else. If you put only an extern declaration without a definition somewhere else, you will have a link error. Using extern is the equivalent of a forward declaration of a function:
/* declaration */
int f(int x);
vs.
/* definition */
int f(int x) {
return x*x;
}
The first means that there is somewhere a function f returning an int and accepting an int as parameter. The latter is the actual function, its code, which also works both as a declaration and a definition.
IMO, this declaration-vs-definition naming is confusing. I hardly remember which one is what, and I usually need to think about it. You should, however, understand the what extern means and what a forward declaration is.
Long story short, defining something means providing all of the necessary information to create that thing in its entirety. However, declaring something means providing only enough information for the computer to know it exists.
Edit: To be clearer: A definition both defines and declares, a declaration ONLY declares. When you are using the extern keyword by definition you are not defining anything. Your confusion stems from the understanding of extern.
#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 have the following source code which interests me.
#include <stdio.h>
extern int foo;
int foo = 32;
int main()
{
printf("%d", foo);
}
This a perfectly normal piece of code, and when I compile it with
gcc -Wall -Wextra -pedantic foo.c
I get no warnings.
And it seems weird, because a variable is defined both as external, and also global in the same file.
I'm quite sure that it's easy to the linker to find the reference for the external variable in the same file, but doesn't it look like a coding error? And if so, why doesn't the compiler warn about this?
There's nothing weird. You first made a declaration of a variable (you promised the compiler that it exist) and then you actually defined it. There's no problem in that.
Also, by default, all variables that aren't local to functions and aren't defined as static are extern.
You seem to misunderstand what extern does. extern simply makes your declaration just a declaration instead of a definition.
int i; //definition of i
extern int i; //declaration of i
It is perfectly normal to have multiple declarations of the same variable, but only one definition should be present in the whole program. Compare this with a function
void f(void); //declaration
void f(void) //definition(and redeclaration)
{
} //definition
In order to use a variable or function, you only need its declaration. Its definition may appear anywhere in the program (the linker will find it). Anywhere can be the same file, another file, or even an external library.
And it's seems weired, because a variable is defined both as external, and also global in the same file.
extern int foo;
says: it declares without defining an object of type int named foo.
int foo = 32;
it declares and defines an object of type int named foo with external linkage.
There is no contradiction and it is valid C code.
The difference is that the former is a declaration -> extern declares a variable and says it will be available somewhere around. You can have as many declarations as you want and the latter is a definition which must be there exactly once.
So there should be no warning and no error.
extern is a way to provide visibility to a variable that is defined elsewhere...
extern is like a promise...
in example.h
extern int g;// promises that this will be in the object code to anything that includes example.h
example. c
int g;
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).