I have read the existing questions on external/internal linkage over here on SO. My question is different – what happens if I have multiple definitions of the same variable with external linkage in different translation units under C and C++?
For example:
/*file1.c*/
typedef struct foo {
int a;
int b;
int c;
} foo;
foo xyz;
/*file2.c*/
typedef struct abc {
double x;
} foo;
foo xyz;
Using Dev-C++ and as a C program, the above program compiles and links perfectly; whereas it gives a multiple redefinition error if the same is compiled as a C++ program. Why should it work under C and what’s the difference with C++? Is this behavior undefined and compiler-dependent? How “bad” is this code and what should I do if I want to refactor it (i’ve come across a lot of old code written like this)?
Both C and C++ have a “one definition rule” which is that each object may only be defined once in any program. Violations of this rule cause undefined behaviour which means that you may or may not see a diagnostic message when compiling.
There is a language difference between the following declarations at file scope, but it does not directly concern the problem with your example.
In C this is a tentative definition. It may be amalgamated with other tentative definitions in the same translation unit to form a single definition. In C++ it is always a definition (you have to use
externto declare an object without defining it) and any subsequent definitions of the same object in the same translation unit are an error.In your example both translation units have a (conflicting) definition of
xyzfrom their tentative definitions.