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.

+3


source to share


3 answers


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).

+2


source


Since C ++ 17 you can write in the header:

inline char const thing[] = "foo";

      



which meets all the criteria.

Note: The variables inline

are external communication, unless explicitly declared as static

. The const

non-internal variable rule applies only to non-string variables.

+1


source


you do not want

const char * const LITERAL="foo";

      

-3


source







All Articles