tapananand
tapananand

Reputation: 4852

Extern in multiple files and possible double definition

I was running the following codes compiled together as: gcc A.c B.c -o combined

Program A:

#include<stdio.h>
int a=1;
int b;
int main()
{
extern int a,b;
fun();
printf("%d %d\n",a,b);
}

Program B:

int a;
int b=2;
int fun()
{
printf("%d %d\n",a,b); 
return 0;
}

On running the "combined" program the output was:

1 2
1 2

Now, I've a few doubts about this one:

  1. Why isn't the output:

    0 2

    1 0

  2. Aren't a and b defined twice?

Please explain these clearly, I've had a lot of problems understanding extern and few of these doubts keep coming from time to time.

Thanks in Advance.

Upvotes: 10

Views: 5597

Answers (4)

tapananand
tapananand

Reputation: 4852

So, I am answering my own question after a long time. Although the statement:

int b; is a decalaration and int b = 2; is the definition

is correct but the reason everyone is giving is not clear.

Had there not been a int b = 2;, int b; was a definition, so what is the difference?

The difference lies in the way the linker handles multiple symbol definitions. There is a concept of weak and strong symbols.

The assembler encodes this information implicitly in the symbol table of the relocatable object file. Functions and initialized global variables get strong symbols. Uninitialized global variables get weak symbols.

So in Program A, int a = 1 is a strong symbol while int b; is a weak symbol, similarly in Program B, int b = 2 is a strong symbol and while int a is weak.

Given this notion of strong and weak symbols, Unix linkers use the following rules for dealing with multiply defined symbols:

  1. Multiple strong symbols are not allowed.
  2. Given a strong symbol and multiple weak symbols, choose the strong symbol.
  3. Given multiple weak symbols, choose any of the weak symbols.

So, now we can argue about what is happening in the above case.

  1. Among int b = 2 and int b, the former is a strong symbol while the latter is weak so b is defined with value 2.
  2. Among int a = 1 and int a, a is defined as 1 (same reasoning).

Hence, the output 1 2.

Upvotes: 4

0decimal0
0decimal0

Reputation: 3984

Because the variables aren't defined twice here; they are declared twice though. The functions take the values from the definition of the variables not from the declaration of the variables.

A declaration introduces an identifier and describes its type.Through declaration we assure to the complier that this variable or function has been defined somewhere else in the program and will be provided at the time of linking. As for example the declaration is:

extern int a;

A definition actually instantiates/implements this identifier. The definition is : int a=5; OR int a;

Just read on this link for further reference.

there is this wonderful post on stackoverflow too .

extern tells the compiler that variable is defined outside so it looks outside the function and there it finds:

int a=1 in program A and int b=2 in program B

For AUTO variables :

int a;//both definition and declaration

For further knowledge of STORAGE CLASSES you can follow this link

int a outside the main or any other function is declaration (i.e GLOBAL) only inside any function its called definition.

Upvotes: 2

Dayal rai
Dayal rai

Reputation: 6606

A variable may be declared many times, as long as the declarations are consistent with each other and with the definition. It may be declared in many modules, including the module where it was defined, and even many times in the same module.

An external variable may also be declared inside a function. In this case the extern keyword must be used, otherwise the compiler will consider it a definition of a local variable, which has a different scope, lifetime and initial value. This declaration will only be visible inside the function instead of throughout the function's module.

Now let me repeat again definition of extern which says "external variable is a variable DEFINED outside any function block"(Please read carefully word given in BOLD). So for the Programe A a have definition but b is just declaration so extern will look for its definition of 'b' which is given in Programe B.So print from Programe A is 1 2.Now lets Talk about Programe B which have declaration for a and definition for b so it is priting value of a from programe A and value of b from current file.

Upvotes: 5

mvv1277
mvv1277

Reputation: 246

As far as I know: Output will be 1 2 and 1 2 because you are defining a and b as a external variables in main function.So it will try to take value from other files also. As far as 2nd question i think compiler is taking initialized values of variable and merging them because both a and b are defined as global variable in both file. Case can be different if both were defined inside function. Any suggestion or other inputs are welcome.

Upvotes: 1

Related Questions