在标题中定义一个大的常量字符串?

时间:2021-04-12 17:03:19

If I define a large constant string in a header file that is included multiple times, will it create multiple copies of the constant string in the executable? (If it does, is there a way to avoid this without needing a separate source file?)

如果我在多次包含的头文件中定义一个大的常量字符串,它是否会在可执行文件中创建常量字符串的多个副本? (如果确实如此,有没有办法避免这种情况而不需要单独的源文件?)

This is what the header looks like:

这是标题的样子:

#pragma once
// this is generated by a tool, so keeping it in one header makes life easy
const uint32 TABLE_SIZE = 65536; 
const uint8 TABLE[TABLE_SIZE] = {...};

2 个解决方案

#1


0  

Looked into how stb_image.h handles it's header-only implementation and found a workable way to include the large string only once in the executable:

看看stb_image.h如何处理它的仅头部实现,并找到了一种可行的方法,只在可执行文件中包含一次大字符串:

The header now looks like this:

标题现在看起来像这样:

#pragma once

// #define IMPLEMENT_TABLE in one and only one cpp file 
// before including this header to define the table

const uint32 TABLE_SIZE = 65536; 
extern const uint8 TABLE[TABLE_SIZE];

#ifdef IMPLEMENT_TABLE

const uint8 TABLE[TABLE_SIZE] = {...};

#endif

#2


0  

In C++, a const variable defined at file scope has internal linkage only, i.e. it's only visible in that translation unit. Defining it in a header file should therefore not cause any errors about multiple definitions.

在C ++中,在文件范围定义的const变量仅具有内部链接,即它仅在该转换单元中可见。因此,在头文件中定义它不应导致有关多个定义的任何错误。

Thus each include will produce new copy of the buffer.

因此每个include都会生成缓冲区的新副本。

Sometimes you can prevent it for example in MSVC for const strings with the option /GS. But it will be not working for char array initializers like yours, it is for const char* p = ... only.

有时你可以阻止它在例如MSVC中使用选项/ GS的const字符串。但它不适用于像你这样的char数组初始化器,它只适用于const char * p = ...

If it does, is there a way to avoid this without needing a separate source file?

如果是这样,有没有办法避免这种情况而不需要单独的源文件?

No, there is not.

不,那里没有。

#1


0  

Looked into how stb_image.h handles it's header-only implementation and found a workable way to include the large string only once in the executable:

看看stb_image.h如何处理它的仅头部实现,并找到了一种可行的方法,只在可执行文件中包含一次大字符串:

The header now looks like this:

标题现在看起来像这样:

#pragma once

// #define IMPLEMENT_TABLE in one and only one cpp file 
// before including this header to define the table

const uint32 TABLE_SIZE = 65536; 
extern const uint8 TABLE[TABLE_SIZE];

#ifdef IMPLEMENT_TABLE

const uint8 TABLE[TABLE_SIZE] = {...};

#endif

#2


0  

In C++, a const variable defined at file scope has internal linkage only, i.e. it's only visible in that translation unit. Defining it in a header file should therefore not cause any errors about multiple definitions.

在C ++中,在文件范围定义的const变量仅具有内部链接,即它仅在该转换单元中可见。因此,在头文件中定义它不应导致有关多个定义的任何错误。

Thus each include will produce new copy of the buffer.

因此每个include都会生成缓冲区的新副本。

Sometimes you can prevent it for example in MSVC for const strings with the option /GS. But it will be not working for char array initializers like yours, it is for const char* p = ... only.

有时你可以阻止它在例如MSVC中使用选项/ GS的const字符串。但它不适用于像你这样的char数组初始化器,它只适用于const char * p = ...

If it does, is there a way to avoid this without needing a separate source file?

如果是这样,有没有办法避免这种情况而不需要单独的源文件?

No, there is not.

不,那里没有。