Use `const char thing [] =" foo ";` in your header file?
I want to create a persistent global char array such that
- It can be used in several translation units.
- The length of the array is inferred from the string literal used to initialize it.
- This string literal exists exactly once in my source (and object files if possible).
- If all translation units have a length access time.
- Has no ODR violations when multiple translation units are linked together.
In theory this should be possible by using const char[]
and putting the braking / definition in the header file in such a way that the data / symbol is included in the COMDAT section, but I don't know if the standard (or even any compilers) support this.
ps Suppose any idiom is used will be used for hundreds of thousands of constants in many files.
Edit: The "cleanest" solution I know of gives all points:
template<bool> struct data_ {
static const char kFoo[];
};
template<> const char data_<true>::kFoo[] = "bar\0other\0stuff\0";
typedef data_<true> data;
#include <stdio.h>
template<typename T, int N>
void Print(T(&var)[N]) { printf("%d %s\n", N, var); }
int main() { Print(data::kFoo); return 0; }
It's still pretty ugly.
OTOH If I just throw out 3b (guaranteed same built-in storage) then this work:
const char kFoo[] = "bar\0other\0stuff\0";
as it has internal linkage by default. A good linker can combine them, but at this point you cannot say anything about the relationship between address / ID equality (i.e., don't pass it to a pointer and use it as an ID). But this is a caveat that is likely to be benign most of the time.
source to share
Title:
#define LITERAL "Hello, world"
extern char const literal[sizeof LITERAL];
One source file:
char const literal[] = LITERAL;
There is still no guarantee that any particular compiler / linker will only make one copy of the string literal (but it does guarantee the requirement to &literal[0]
be the same in all units).
source to share