I declared a variable i in temp2.h
extern i;
which contains just one above line
and made another file
temp3.c
#include<stdio.h>
#include<temp2.h>
int main ()
{
extern i;
i=6;
printf("The i is %d",i);
}
When I compiled above as
cc -I ./ temp3.c
I got following errors
/tmp/ccJcwZyy.o: In function `main':
temp3.c:(.text+0x6): undefined reference to `i'
temp3.c:(.text+0x10): undefined reference to `i'
collect2: ld returned 1 exit status
I had declared extern in temp3.c above as K R page 33 says as I mentioned in above post. I tried another way for temp3.c with same header file temp2.h
#include<stdio.h>
#include<temp2.h>
int main ()
{
i=6;
printf("The i is %d",i);
}
and compiled it cc -I ./ temp3.c
and got following error
/tmp/ccZZyGsL.o: In function `main':
temp3.c:(.text+0x6): undefined reference to `i'
temp3.c:(.text+0x10): undefined reference to `i'
collect2: ld returned 1 exit status
I also tried
#include<stdio.h>
#include<temp2.h>
int main ()
{
extern i=6;
printf("The i is %d",i);
}
compiled this one
cc -I ./ temp3.c
got same error as in post 1
temp3.c: In function ‘main’:
temp3.c:5: error: ‘i’ has both ‘extern’ and initializer
So I have tried at least 3 different ways to use extern but non of them worked.
When you declare a variable using extern
, you are telling the compiler that the variable was defined elsewhere and the definition will be provided at the time of linking. Inclusion is a different thing altogether.
extern
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.
-The C Programming Language
A variable must be defined once in one of the modules(in one of the Translation Units) of the program. If there is no definition or more than one, an error is produced, possibly in the linking stage (as in example 1 and 2).
Try something like the following
a.c
int i =10; //definition
b.c
extern int i; //declaration
int main()
{
printf("%d",i);
}
Compile, link and create an executable using
gcc a.c b.c -o executable_name
or
gcc -c a.c // creates a.o
gcc -c b.c // creates b.o
Now link the object files and create an executable
gcc a.o b.o -o executable_name
The first program said:
i
(implicitly of type int
) is defined somewhere else - but you didn't define it anywhere.The second program tried to use a variable for which there was no declaration at all.
The third program tried to declare a variable without an explicit type (used to be OK; not allowed in C99), and said:
i
is defined somewhere else, but I want to initialize it here.You are not allowed to do that.
So, the compiler is correct in all cases.
The declaration in the header 'temp2.h' should be fixed to extern int i;
first. The implicit int
is long obsolete.
You could fix the first example in several ways:
#include <stdio.h>
#include <temp2.h>
int main()
{
extern int i;
i=6;
printf("The i is %d",i);
return 0;
}
int i;
This defines the variable after the function - aconventional but legitimate. It could alternatively be in a separate source file that is separately compiled and then linked with the main program.
The second example could be fixed with:
#include <stdio.h>
#include <temp2.h>
int main()
{
int i=6;
printf("The i is %d",i);
return 0;
}
It is important to note that this example now has two variables called i
; the one declared in temp2.h
(but not actually referenced anywhere), and the one defined in main()
. Another way of fixing it is the same as in the first possible fix:
#include <stdio.h>
#include <temp2.h>
int main()
{
i=6;
printf("The i is %d",i);
return 0;
}
int i;
Again, aconventional placement, but legitimate.
The third one can be fixed by similar methods to the first two, or this variant:
#include <stdio.h>
#include <temp2.h>
int i;
int main()
{
extern int i;
i=6;
printf("The i is %d",i);
return 0;
}
This still declares i
in <temp2.h>
but defines it in the source file containing main()
(conventionally placed - at the top of the file). The extern int i;
insides main()
is doubly redundant - the definition in the source file and the declaration in the header mean that it does not need to be redeclared inside main()
. Note that in general, the declaration in the header and the definition in the source file are not redundant; the declaration in the header provides a consistency check with the definition, and the other files that also use the variable and the header are then assured that the definition in the file containing main()
is equivalent to the definition that the other file is using too.
extern is declaration mechanism used to tell the compiler that the variable is defined in another file.
My Suggestion is that you define a variable in a ".c" file and then add the extern declaration in the corresponding ".h" file. In this way, the variable declaration will be available to all the source files which includes this header file and also it will be easier for one to identify in which ".c" it is actually defined.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With