Global variables with the same name

You know from the Build process that the compiler will export the global variables to the assembler

and the assembler encode these variables implicitly and put them in the symbol table of object file and finally the linker take these object files and produce .elf or .dwarf .

Theses global variables can be weak symbols or strong symbols:

The weak symbol is the unintialized variable and the strong symbols are the intialized variables and functions.

The linker use the following rules to deal with the multiple defined global variables

Rule 1: Multiple strong symbols (with same variable name) 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.

/* test1.c */

int x = 1521;

int main()

{

  return 0;

}

  

/* test2.c */

int x = 1521;

void f()

{

}

Based on the rule1 the linker will produce error because the strong symbol x is defined twice .

/* test1.c */

void f(void);

int x = 15213;

int main()

{

  f();

  printf("x = %d\n", x);

  return 0;

}

  

/* test2.c */

int x;

void f()

{

  x = 15212;

}

At run time, function f() changes the value of x from 15213 to 15212 .Notice that the linker normally gives no indication that it has detected multiple definitions of x.(rule2)

The same thing can happen if there are two weak definitions of x (rule 3):

/*test1.c*/

#include <stdio.h>

void b(void);


int x;

int main()

{

    x = 2016;

    b();

    printf("x = %d ",x);

    return 0;

}

/*test2.c*/

#include <stdio.h>

 

int x;

 

void b()

{

    x = 2017;

     

}

The application of rules 2 and 3 can introduce some insidious run-time bugs that are unclear to the unwary programmer, especially if the duplicate symbol definitions have different types.

Example : “x” is defined as an int in one module and a double in another.

/*a.c*/

#include <stdio.h>

void b(void);

 

int x = 2016;

int y = 2017;

int main()

{

    b();

    printf("x = 0x%x y = 0x%x \n", x, y);

    return 0;

}

/*b.c*/

double x;

 

void b()

{

    x = -0.0;

}

This program will produce x = 0x0 y = 0x80000000 
as x is double and y & x in the another file are integer and x took the double size of both of two variables 
so y is got corrupted 


So to avoid these tricky bugs you can use

gcc -fno-common flag, which triggers an error if it encounters multiply defined global symbols.

要查看或添加评论,请登录

Mohamed Salem的更多文章

  • Management of Bluetooth devices in Linux

    Management of Bluetooth devices in Linux

    Here I will talk about how to connect with a Bluetooth device in Linux using a command-line utility called…

  • Concurrent Queue

    Concurrent Queue

    Did you hear about the queue as a data structure ? ---- of course yes, But what is the concurrent queue, in nutshell…

    1 条评论
  • Priority Queue in C++

    Priority Queue in C++

    A priority queue in c++ is a type of container adapter, which processes only the highest priority element, i.e.

  • Bubble Sort in CPP

    Bubble Sort in CPP

    We will explain the simple sorting Algorithm which (Bubble Sort) Bubble Sort is a simple algorithm which is used to…

  • Function before and after main()

    Function before and after main()

    Did you start to execute functions before and after the main() function ? you have two solutions to do that : first…

  • Command_line_arguments

    Command_line_arguments

    ???? ???? ?????? ???? ???????? ?? ?? command line arguments ???? ???? ???? ???????? ????? ????????? ???? ???? :O ????…

  • C_prototypes

    C_prototypes

    ??? ???? ?????? ????? ??????? ?? ????? ??? 1) int main(){} void main(){} ?????? ??????? ??? ??????? ????????? ??????…

  • Data Structures

    Data Structures

    https://drive.google.

  • Most Common Questions in Embedded C

    Most Common Questions in Embedded C

    https://drive.google.

社区洞察

其他会员也浏览了