We are trying to compile a program on a Tandem X series machine, but we are getting errors of the form, "Illegal duplicate definition of the initialized data item in C and/or C++ ". The same code compiles successfully for us on aTandem S series machine.
We have following file Structure:
/---AddressMap.h----/
#ifndef ADDRESSMAP // Header file macro
#define ADDRESSMAP // Header file macro
typedef map<long,char*,less<long> > gAddress; data type
gAddress::iterator gAddressIterator; // define iterator
gAddress gAddressMap; // define variable
#endif//ADDRESSMAP
/*file1.cpp:-> First File using the AddressMap */
#include "AddressMap.h" // include file
/*file2.cpp:-> Second File also using the AddressMap */
#include "AddressMap.h" // include file
Problem
Both files are compiled successfully, but linking them together fails with ...
Illegal duplicate definition of the initialized data item gAddressMap in file1.o and in file2.o
Since both files need to access this variable, both have included the header file; maybe that's responsible for the error. Also, it's existing code, so we want to avoid major code change. In particular, we want to keep the same header file and variable names.
How can we resolve this error?
Tandem Details:
Each compilation unit -- roughly speaking, one source file and all files directly or indirectly #include
d into it -- is compiled separately. Therefore, if you include your particular header into two separate files, both of them compile the declarations
gAddress::iterator gAddressIterator; // define iterator
gAddress gAddressMap; // define variable
Because these are not declared extern
, they constitute definitions of those objects. As a result, each file that includes the header contains a definition of each of those objects, and each object file has its own version of each of those. C++ permits multiple declarations of the same object, but only one definition in each complete program. Because each of your modules has a definition of gAddressMap
and gAddressIterator
, you cannot form a conforming program that combines the two.
The solution has two parts. First, you must ensure that the header file's declarations are not definitions. You achieve this by declaring them extern
:
extern gAddress::iterator gAddressIterator; // declare iterator
extern gAddress gAddressMap; // declare variable
Second, you must put actual definitions somewhere, in exactly one file among all those you intend to combine into one program. If there is a source file containing functions for initializing or otherwise managing these objects, then that would be a promising place, but not a header file that multiple other files might include.