Reputation: 1147
I want to avoid #defines in my code. Accordingly, I have the following in a header file :
#ifndef __GATENAMES__
#define __GATENAMES__
namespace GateNames
{
const char* CBSD_GATE_TO_SAS = "CbsdGate_SAS_INOUT";
const char* CBSD_GATE_TO_SAS_OUT = "CbsdGate_SAS_INOUT$o";
const char* CBSD_GATE_TO_SAS_IN = "CbsdGate_SAS_INOUT$i";
const char* SAS_GATE_TO_CBSD = "SasGate_CBSD_INOUT";
const char* SAS_GATE_TO_ESC = "SasGate_ESC_INOUT";
const char* SAS_GATE_TO_ESC_OUT = "SasGate_ESC_INOUT$o";
const char* SAS_GATE_TO_ESC_IN = "SasGate_ESC_INOUT$i";
};
#endif
This header file is included in various places in my code. However, the linker complains that the symbols are multiply defined:
../out/gcc-debug/src/CbsdSim.o:(.data.rel.local+0x0): multiple definition of `GateNames::CBSD_GATE_TO_SAS'
How can I get around this problem? Thanks.
Upvotes: 2
Views: 1583
Reputation: 49986
The reason for your linker errors is that non const variables have external linkage, and since you defined them in multiple translation units (by including a header), linker complains.
There are three ways to fix your code. First is to change linkage of your const char*
string literals, by making them static. This way they have internal linkage, and each translation unit which includes them will not share them with other translation units - so also linker will not complain:
static const char* CBSD_GATE_TO_SAS = "CbsdGate_SAS_INOUT";
^^^^^^
Second one is to make them const:
const char* const CBSD_GATE_TO_SAS = "CbsdGate_SAS_INOUT";
^^^^^
which is actually quite similar to making them static, they have now internal linkage.
Third way is to declare them in header file and define in one single translation unit.:
// in header file
namespace GateNames
{
extern const char* CBSD_GATE_TO_SAS ;
};
in some .cpp file:
namespace GateNames
{
const char* CBSD_GATE_TO_SAS = "CbsdGate_SAS_INOUT";
};
Upvotes: 1
Reputation:
Firstly, names like this __GATENAMES__
, (any name starting with an underscore and an uppercase letter or containing two consecutive underscores) is reserved for the C++ implementation - you shgould not be creating such names in your own code.
Secondly, your constness is a bit mixed up, instead of things like:
const char* CBSD_GATE_TO_SAS = "CbsdGate_SAS_INOUT";
you want:
const char * const CBSD_GATE_TO_SAS = "CbsdGate_SAS_INOUT";
In other words, it's the pointer that's got to be const to limit the linkage of the pointer, not the thing pointed to (although in this case that also has to be const).
Upvotes: 6