Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Complicated when compiling in c++ but not in c (gcc)

I have problem with multiply declaration in c++, but not in c. You could see code for more information.

file main.c

#ifndef VAR
#define VAR
int var;
#endif
int main(){}

file other.c

#ifndef VAR
#define VAR
int var;
#endif

Compile with gcc

gcc main.c other.c
>> success

Compile with g++

g++ main.c other.c
Output:
/tmp/ccbd0ACf.o:(.bss+0x0): multiple definition of `var'
/tmp/cc8dweC0.o:(.bss+0x0): first defined here
collect2: ld returned 1 exit status

My gcc and g++ version:

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.
like image 526
transang Avatar asked Aug 08 '12 23:08

transang


People also ask

Is GCC compiler only for C?

GCC, formerly for "GNU C Compiler", has grown over times to support many languages such as C ( gcc ), C++ ( g++ ), Objective-C, Objective-C++, Java ( gcj ), Fortran ( gfortran ), Ada ( gnat ), Go ( gccgo ), OpenMP, Cilk Plus, and OpenAcc. It is now referred to as "GNU Compiler Collection".

Does GCC compile both C and C++?

Difference between GCC and G++ GCC stands for GNU Compiler Collections which is used to compile mainly C and C++ language. It can also be used to compile Objective C and Objective C++.

Should I compile with GCC or G ++?

gcc is used to compile C program while g++ is used to compile C++ program. Since, a C program can also be compile complied through g++, because it is the extended or we can say advance compiler for C programming language.

Does GCC work with C?

GCC is an integrated distribution of compilers for several major programming languages. These languages currently include C, C++, Objective-C, Objective-C++, Java, Fortran, and Ada.


1 Answers

Your code is formally incorrect in both C and C++ due to multiple definitions of variable var. It is just that this type of error was traditionally overlooked by C compilers as a popular non-standard extension. This extension is even mentioned in C language specification

J.5 Common extensions

The following extensions are widely used in many systems, but are not portable to all implementations. [...]

J.5.11 Multiple external definitions

There may be more than one external definition for the identifier of an object, with or without the explicit use of the keyword extern; if the definitions disagree, or more than one is initialized, the behavior is undefined (6.9.2).

But formally, you have absolutely the same multiple-definition error in both C and C++ languages. Ask your C compiler to behave more pedantically (disable extensions, if it has an option for that) and your C compiler shall also generate the very same error as your C++ compiler.

Again, you code contains multiple definitions of variable var, which is an error in both C and C++. Your #ifdef directives do not solve anything at all. Preperocessor directives cannot help you here. Preprocessor works locally and independently in each translation unit. It can't see across translation units.

If you want to create a global variable (i.e. the same variable shared by all translation units), you need to make one and only one definition of that variable

int var;

in one and only one translation unit. All other translation units should receive non-defining declarations of var

extern int var;

The latter is typically placed in a header file.

If you need an individual, independent variable var in each translation unit, simply define it in each translation unit as

static int var;

(although in C++ this usage of static is now deprecated and superseded by nameless namespaces).

like image 83
AnT Avatar answered Sep 29 '22 08:09

AnT