在头文件中使用"const char thing[] = "foo" ;"?



我想创建一个常量全局字符数组,这样

  • 它可以在多个翻译单元中使用
  • 数组的长度是从用于初始化它的字符串文字中推导出来的
  • 这个字符串文字在我的源文件(如果可能的话,还有对象文件)中只存在过一次
  • 其中所有的翻译单元都有编译时访问的长度
  • 当多个翻译单元链接在一起时,没有ODR冲突

理论上,通过使用const char[]并在头文件中放入减速/定义,以迫使数据/符号进入COMDAT部分,这应该是可能的,但我不知道标准(甚至任何编译器)是否支持这一点。

p.s.假设使用的任何习惯用法都将用于许多文件中的数百到数千个常量。


编辑:我所知道的"最干净"的解决方案是:

template<bool> struct data_ {
  static const char kFoo[];
};
template<> const char data_<true>::kFoo[] = "barotherstuff";
typedef data_<true> data;

#include <stdio.h>
template<typename T, int N>
void Print(T(&var)[N]) { printf("%d %sn", N, var); }
int main() { Print(data::kFoo); return 0; }

这仍然相当丑陋。


OTOH如果我只是抛出3b(保证相同的存储模块内联),那么这项工作:

const char kFoo[] = "barotherstuff";

因为默认情况下它具有内部链接。一个好的链接器可以合并这些,但在这一点上,您不能对地址/标识符的相等性之间的关系说任何话(即,不要将其强制转换为指针并将其用作标识)。但这是一个警告,几乎一直都是良性的

标题:

#define LITERAL "Hello, world"
extern char const literal[sizeof LITERAL];

一个源文件:

char const literal[] = LITERAL;

仍然不能保证任何特定的编译器/链接器只生成字符串文本的一个副本(但它确实保证了&literal[0]在所有单元中都相同的要求)。

由于C++17,您可以在头中写入:

inline char const thing[] = "foo";

其满足所有标准。

注意:inline变量具有外部链接,除非显式声明为static。关于const变量默认为内部链接的规则仅适用于非内联变量。

你不想要

const char * const LITERAL="foo";

相关内容

  • 没有找到相关文章

最新更新