Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Non-initialized global variable(s) of different type but with the same name - strange link behaviour

Tags:

c

gcc

First of all, please help me to find a better title which will describe the situation more accurately. I created the following simplified version of a problem I stumbled on when debugging real-world (embedded) code.

Consider the following code of file t1.c:

#include <stdio.h>

int A;

void f() { printf("%d\n", A); }

extern void g();

void main(void)
{
    g(); A=1; g();
    A++;
    f();
}

and the code of t2.c:

#include <stdio.h>

double A;

void g()
{
    A += 1.0;
    printf("%f\n", A);
}

Now compiling and running the code like this:

gcc -Wall t1.c t2.c -o t && ./t

gives

1.000000
2.000000
1

Note that both files contain a global variable call A which has a different type. I expected a link error because the symbol A exists multiple times.

I actually get a link warning (object size changes in different .o) when I initialize one of the two variables, an error (multiple definitions) when I initialize both of them.

I tried this with gcc 4.7 and 4.4.

Is this expected behavior? If so, is there something I can do to instruct the toolchain (gcc-based) to warn about it?

Is this a bug?

like image 319
Patrick B. Avatar asked Jun 28 '13 19:06

Patrick B.


People also ask

What happens if you name a local variable with the same name as a global variable?

If a global and a local variable with the same name are in scope, which means accessible, at the same time, your code can access only the local variable.

What are uninitialized global variables?

In computing, an uninitialized variable is a variable that is declared but is not set to a definite known value before it is used. It will have some value, but not a predictable one. As such, it is a programming error and a common source of bugs in software.

Can 2 global variable have same name?

It should give error as we cannot declare same name variables in same storage class.

What happens if you define two global variables in different C files with the same name?

There is no problem if it is inside a function as it is a local variable. If it is a global declaration, it depends on the linker. You can get a link error (or if you use options to direct it to do so). Otherwise they will be consolidated into one location as if you had declared them external.


1 Answers

Yes, compile with -fno-common option to get the linker error:

$ gcc -Wall -fno-common -c t1.c
$ gcc -Wall -fno-common -c t2.c
$ gcc t1.o t2.o -o t
t2.o:t2.c:(.bss+0x0): multiple definition of `_A'
t1.o:t1.c:(.bss+0x0): first defined here
collect2: error: ld returned 1 exit status
$

If you want to compile this in one line you can also pass the --warn-common to the linker (here with --fatal-warnings to have an error instead of a warning):

$ gcc -Wl,--fatal-warnings,--warn-common -Wall t1.c t2.c -o t
/tmp/cc1xQo79.o: warning: common of `_A' overriding smaller common
/tmp/ccLnhxoe.o: warning: smaller common is here
collect2: error: ld returned 1 exit status
$

By default gcc performs various optimizations of C undefined behaviors as an extension. C allows any implementation to stop translation in presence of such a program, so except if you have excellent reasons to do it, you should avoid it.

like image 137
ouah Avatar answered Oct 04 '22 08:10

ouah