我想创建一个常量全局字符数组,满足以下条件:
注:假设将使用任何惯用语法用于数百到数千个常量,并跨越许多文件。
编辑:我知道的“最干净”的解决方案如下,符合上述所有要求:
- 可以在多个翻译单元中使用。
- 数组的长度由用于初始化它的字符串字面值推导出。
- 该字符串字面值在我的源代码(如果可能,也在目标文件中)中只存在一次。
- 所有翻译单元在编译时都能访问到长度。
- 当链接多个翻译单元时没有ODR冲突。
const char[]
并以强制数据/符号进入COMDAT节的方式将声明/定义放置在头文件中,应该是可能的,但我不知道标准(甚至任何编译器)是否支持这样做。注:假设将使用任何惯用语法用于数百到数千个常量,并跨越许多文件。
编辑:我知道的“最干净”的解决方案如下,符合上述所有要求:
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; }
这仍然相当丑陋。
另一方面,如果我只放弃3b(保证相同的存储模块内联),那么这份工作将得以实现:
const char kFoo[] = "bar\0other\0stuff\0";
因为默认情况下它具有内部链接。一个好的链接器可以合并这些,但此时您不能说关于地址/标识符相等性之间的关系(即不要将其转换为指针并将其用作标识)。但这是一个警告,几乎在大多数情况下都是无害的。
因为默认情况下它具有内部链接。一个好的链接器可以合并这些,但此时您不能说关于地址/标识符相等性之间的关系(即不要将其转换为指针并将其用作标识)。但这是一个警告,几乎在大多数情况下都是无害的。
const
但不是extern
)将获得内部链接,意味着每个翻译单元中都会有一个不同的对象。 - dypconst
而不是extern
无法通过3b点。模板解决方案很丑陋,需要重复名称和大部分类型。函数静态解决方案需要自动返回类型(C++14,尚未实现),否则会失败4点。我不确定如何将单独的存储空间应用于所有点的2、3a和4。 - BCS