"multiple value definition" when compiling a C program with an uninitialized global in g ++, but not gcc

I am trying to understand the use of the extern expression and global variable in header files, so I came up with the following test program written in C.

File main.c

//main.c #include "global.h" #include <stdio.h> int nExternValue = 6; int main(int argc, char* argv[]) { printf("%d \n", nValue); printf("%d \n", nExternValue); AddToValue(); printf("%d \n", nValue); printf("%d \n", nExternValue); } 

Global.h file

 #ifndef _GLOBAL_H #define _GLOBAL_H //WRONG! do not declare a variable here int nValue; //OK! extern variable makes it a global accessable variable extern int nExternValue; //OK! function prototype can be placed in h file int AddToValue(); #endif 

and the AddValue.c file that implements the AddToValue function.

 #include "global.h" int AddToValue() { nValue++; nExternValue++; } 

I compiled the application using gcc and ran it:

 $ gcc main.c AddValue.c -o test $./test 0 6 1 7 

I ran the application using g ++ and got the following linker error:

 $ g++ main.c AddValue.c -o test /tmp/ccFyGDYM.o:(.bss+0x0): multiple definition of `nValue' /tmp/cc3ixXdu.o:(.bss+0x0): first defined here collect2: ld returned 1 exit status 

Why doesn't the gcc linker generate an error? I, although the variable nValue will be declared several times, and this will lead to an error!

 $ gcc --version gcc (Ubuntu/Linaro 4.6.3-1ubuntu5) 4.6.3 Copyright (C) 2011 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. $ g++ --version g++ (Ubuntu/Linaro 4.6.3-1ubuntu5) 4.6.3 Copyright (C) 2011 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+4
source share
2 answers

C and C ++ are different languages. The fact is that the above program is an active C program, but in a poorly formed C ++ program. You have violated one C ++ definition rule. There is no corresponding rule in C.

When compiling with gcc, you compile the above text as a C program. When compiling with g ++, you compile the above text as a C ++ program.

+5
source

When compiling with gcc, an uninitialized global variable (such as nValue) will be treated as a generic character. The same common character occurring in different compilation units will be merged during the connection. If compiled with g ++ (which means that the source program will be treated as a C ++ program), the uninitialized global variable is implicitly initialized to the default value 0. Since global.h is included in several source files, the compiler will consider the nValue character, defined several time.

Please also see this post: Why is an uninitialized global variable a weak symbol?

+3
source

All Articles