For some reason, none of the answers so far has helped explain the difference between the whole NUM_SOCIODEM_FILES object and the SOCIODEM_FILENAMES array SOCIODEM_FILENAMES . The latter causes a linker error for reasons already explained: because you include the header file in several implementation files. However, the former would join without any problems (because there really are no problems with declaring NUM_SOCIODEM_FILES ). Why?
The reason for this is because your NUM_SOCIODEM_FILES object NUM_SOCIODEM_FILES declared const . In C ++, const objects have an internal link by default, which means that they do not cause binding problems, even if they are defined in multiple implementation files. In other words, in C ++ your NUM_SOCIODEM_FILES equivalent
static const int NUM_SOCIODEM_FILES = 5;
therefore, it does not lead to any binding problems.
At the same time, your SOCIODEM_FILENAMES not declared a constant, so by default it gets an external connection and ultimately leads to linker errors. But if you declare your SOCIODEM_FILENAMES as const , the problem will disappear.
const char * const SOCIODEM_FILENAMES[ NUM_SOCIODEM_FILES ] = { ...
Notice where the extra const added in the declaration. If you just add this extra const and leave everything else as it is (i.e., save the definition if SOCIODEM_FILENAMES in the header file), the linker will not report an error even if you include the header file in several translation units.
This is not recommended because this way you will pass your internal SOCIODEM_FILENAMES link and get a separate copy of the SOCIODEM_FILENAMES array in each translation unit - something that might work fine, but still makes very little sense. So, for your array it is usually better to use the extern approach recommended in other answers.
However, note that you should not usually do this for the declaration NUM_SOCIODEM_FILES !!! This is normal as indicated in the header file. If you are not trying to do something unusual, scalar constants usually need to be defined with an initializer in the header files - thus, they can be considered as compile-time constants in all translation units, which is quite valuable. Therefore, beware of the strange tips present in some other answers to move the definition of NUM_SOCIODEM_FILES to a .cpp file - this actually does not make sense and is absolutely wrong.