【问题标题】:Using C++ constexpr can create symbol duplication?使用 C++ constexpr 可以创建符号重复?
【发布时间】:2016-12-16 15:58:43
【问题描述】:

我正在尝试定义一些字符串文字和一些常量结构。

做了一些测试,我意识到使用:

constexpr char* name = "name";
constexpr Structure data = {1, 2, 3};

在编译不同的库时,我必须在内存中创建名称地址,并且每个库的数据都不同。 这我真的不想发生。

我又做了一个测试:

constexpr char* name() { return "name"; }
constexpr Structure data() { return Structure{1, 2, 3}; };

当以这种方式编译不同的库时,我发现(至少使用 GCC)内存中名称和数据的地址总是相同的! 即使“数据”在理论上是复制的。

我试图研究这种行为,但我找不到这种行为是否特定于 GCC,或者符号的重用是否符合 C++ 标准。

已编辑 确保 constexpr 数据不会在所有使用它的库中重复的最佳方法是什么?

【问题讨论】:

  • 这是在链接器级别完成的。 MS 将此称为相同的 COMDAT 折叠(通用数据)。大多数开发人员都希望这种情况发生。如果链接器没有提供关闭它的开关,您可能不得不求助于堆。
  • 我的问题更多是关于我是否可以依赖它。折叠公共数据块对我来说绝对是可取的。
  • 对不起,重读了这个问题,我意识到我问的问题与我真正想要的相反。编辑澄清。
  • 知道了。为什么不通过 const ref 返回以删除任何副本的想法?
  • 我试过了。我收到有关返回临时引用的编译错误。使用 static 给我一个关于在 constexpr 中禁止使用静态的编译错误。

标签: c++ c++11 gcc one-definition-rule


【解决方案1】:

根据 cmets,我怀疑你会想要这样的东西:

struct Structure { int x, y, z; };
static constexpr char const* _name = "name";
static constexpr Structure _data = { 1, 2, 3 };

constexpr char const* get_name() noexcept { return _name; }
constexpr Structure const& get_data() noexcept { return _data; }

那么其他翻译单元会有类似下面的代码:

constexpr char const* n = get_name();
constexpr Structure const& d = get_data();

printf("n: %s", n);
printf("d: %d %d %d", d.x, d.y, d.z);

如果 TU 对变量有作用域,则可以静态断言

static_assert(_name == n, "");
static_assert(&_data == &d, "");

希望这会有所帮助。

【讨论】:

  • 我还发现了另一种选择,即将 constexpr 符号嵌入到一个类中。这迫使编译器在 C++ 文件中需要一个符号,但也总是给我正确的结果。我不得不使用 char[] 而不是 char*,但这是我需要的唯一区别。
猜你喜欢
  • 2019-02-05
  • 2016-04-30
  • 2020-03-13
  • 2014-10-24
  • 1970-01-01
  • 2015-07-08
  • 2021-12-29
  • 2019-04-18
  • 1970-01-01
相关资源
最近更新 更多