I'm having two .c files: A1.c and A2.c
A1.c as follows:
int i=0;
void main()
{}
A2.c as follows:
int i=0;
void func()
{}
It compiles well but when I try to link these two .o files, there is a "multiple definition of i" error.
I understand i
is a global variable here, but doesn't it need an extern
keyword to be used in other files. And in my project I'm not using the extern
. So how come I get an error?
What is Visibility of a variable in C? Visibility of a variable is defined by how a variable is accessible inside a program. A variable is visible within its scope and hidden outside the scope. A variable's visibility controls how much of the rest of the program may access it.
In computer programming, a global variable is a variable with global scope, meaning that it is visible (hence accessible) throughout the program, unless shadowed.
C has four kinds of scopes: block scope. file scope. function scope.
The scope of a declaration is the part of the program for which the declaration is in effect. C/C++ use lexical scoping. The lifetime of a variable or object is the time period in which the variable/object has valid memory. Lifetime is also called "allocation method" or "storage duration."
At compile time, the compiler exports each global symbol to the assembler as either strong or weak, and 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.
Given this notion of strong and weak symbols, Unix linkers use the following rules for dealing with multiply defined symbols:
Rule 1: Multiple strong symbols are not allowed.
Rule 2: Given a strong symbol and multiple weak symbols, choose the strong symbol.
Rule 3: Given multiple weak symbols, choose any of the weak symbols.
Your code, A1.c as follows:
int i=0; // Strong Symbol
void main() {}
A2.c as follows:
int i=0; // Strong symbol
void func() {}
As per Rule 1 this is not allowed.
For more detailed information: http://www.geeksforgeeks.org/how-linkers-resolve-multiply-defined-global-symbols/
Long story short, a statement like
extern int i;
is a declaration, while the statement
int i=0;
is a definition.
In C you can declare a variable many times in a program, but you can define it only once.The first statement signifies to A2 that the definition of the variable i is in another file.For one I can't understand why you are so apprehensive about using "extern".
In C, a global variable can be accessed from another compilation unit as long as this other compilation unit sees that it exists, by declaring it extern
. The linker makes the job have linking the extern declaration and the definition in another .c.
If you want it to be only visible to the .c that you are compiling, you must specify it as static
static int i = 0;
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