Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

what is the visibility/scope of a global variable in C?

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?

like image 305
henryyao Avatar asked Apr 16 '13 13:04

henryyao


People also ask

What is visibility of variables in C?

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.

What is the scope of a global variable?

In computer programming, a global variable is a variable with global scope, meaning that it is visible (hence accessible) throughout the program, unless shadowed.

How many variables scopes are there in C?

C has four kinds of scopes: block scope. file scope. function scope.

What is scope and lifetime of a variable in C?

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."


3 Answers

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/

like image 175
Nash Avatar answered Sep 25 '22 21:09

Nash


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".

like image 42
Rüppell's Vulture Avatar answered Sep 22 '22 21:09

Rüppell's Vulture


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;
like image 32
J_D Avatar answered Sep 23 '22 21:09

J_D