【问题标题】:Final binary size: constexpr variable vs constexpr function最终二进制大小:constexpr 变量与 constexpr 函数
【发布时间】:2016-08-04 23:01:32
【问题描述】:

首先,我已经阅读了这篇内容非常丰富的answer,关于定义 constexpr 变量与 constexpr 函数之间的风格差异。我的问题与使用这两者时二进制文件的最终大小有关。考虑这段代码:

// approach 1
template <typename T>
struct foo
{
  static constexpr char name[] = "mickey";
};

// approach 2
template <typename T>
struct bar
{
  static constexpr const char* getName() { return "mickey"; }
};

const char* func1() { return foo<int>::name; }
const char* func2() { return foo<double>::name; }

const char* func3() { return bar<int>::getName(); }
const char* func4() { return bar<double>::getName(); }

在此godbolt 链接中查看此代码。虽然方法 1 返回名称的不同副本,但方法 2 只为不同 T 的所有不同实例返回一个副本。事实上,当我创建 100 种不同类型时,方法 2 导致了一个相当小的二进制文件。想知道有没有人经历过类似的事情。

【问题讨论】:

  • 你有什么问题?您是否要求我们确认函数占用了可执行映像中的空间?嗯,是的,是的。
  • 回复了下面的最佳答案。

标签: c++ constexpr


【解决方案1】:

嗯,这两种方法并不完全相同。有些事情你可以用foo&lt;T&gt;::name 做而你不能用bar&lt;T&gt;::getName() 做:我可以用一个指针指向它,我可以引用它。这种能力可以防止不同的foo&lt;T&gt;::names 相同。

但是使用getName(),就不存在这样的问题。你只是得到一个prvalue - 你不能拿它的地址。不同的bar&lt;T&gt;::getName 函数本身必须不同,但底层存储不一样。

【讨论】:

  • 虽然正确,但如果您的目标是最小化可执行文件的大小,这并没有真正帮助,这个问题的存在证明了这一点。不是你的错——完全不清楚是什么问题
  • @LightnessRacesinOrbit 我把这个问题解释为“为什么有区别?”
  • @LightnessRacesinOrbit:抱歉问题不清楚。巴里的答复正是我所寻求的。 (不过我是通过一种复杂的方式到达那里的)
  • 你不能使用foo&lt;T&gt;::name,因为它是constexpr。我错了吗?您确实不能获取指针或对其的引用
  • 当链接器参与游戏时,struct S { static constexpr int v = 42; }; int main() { const int *p = &amp;S::v; } 会导致对S::v 的未定义引用。因为您不能获取constexpr 变量的地址。当然,除非您在某处添加 constexpr int S::v;,但要在 odr 中使用 constexpr 确实没有多大意义。
猜你喜欢
  • 2015-05-04
  • 2020-10-08
  • 2021-04-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多