I have a character array defined in a header
//header.h
const char* temp[] = {"JeffSter"};
The header if #defined guarded and has a #pragma once at the top. If this header is included in multiple places, I get an LNK4006 – char const * * temp already defined in blahblah.obj. So, I have a couple of questions about this
- Why does this happen if I have the guards in place? I thought that they prevented the header from being read in after the first access.
- Why do the numerous enums in this header not also give the LNK4006 warnings?
- If I add static before the signature, I don’t get the warning. What are the implications of doing it this way.
- Is there a better way to do this that avoids the error, but lets me declare the array in the header. I would really hate to have a cpp file just for an array definition.
Include guards make sure that a header is included only once in one file (translation unit). For multiple files including the header, you want the header to be included in each file.
By defining, as opposed to declaring variables with external linkage (global variables) in your header file, you can only include the header in once source file. If you include the header in multiple source files, there will be multiple definitions of a variable, which is not allowed in C++.
So, as you have found out, it is a bad idea to define variables in a header file for precisely the reason above.
Because, they don’t define “global variables”, they’re only declarations about types, etc. They don’t reserve any storage.
When you make a variable
static, it has static scope. The object is not visible outside of the translation unit (file) in which it is defined. So, in simple terms, if you have:in your header, each source file in which you include the header will get a separate
intvariablei, which is invisible outside of the source file. This is known as internal linkage.If you want the array to be one object visible from all your C++ files, you should do:
in your header file, and then include the header file in all the C++ source files that need the variable
array. In one of the source (.cpp) files, you need to definearray:You should include the header in the above source file as well, to allow for catching mistakes due to a difference in the header and the source file.
Basically,
externtells the compiler that “arrayis defined somewhere, and has the typeint, and sizeSIZE“. Then, you actually definearrayonly once. At link stage, everything resolves nicely.