Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

warning in extern declaration

Tags:

c

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.

like image 423
reality displays Avatar asked Nov 25 '10 06:11

reality displays


3 Answers

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
like image 142
Prasoon Saurav Avatar answered Oct 16 '22 19:10

Prasoon Saurav


The first program said:

  • The variable 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:

  • The variable 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.

like image 32
Jonathan Leffler Avatar answered Oct 16 '22 20:10

Jonathan Leffler


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.

like image 3
Jay Avatar answered Oct 16 '22 21:10

Jay