【问题标题】:Confusion about in-class initialization of static data members关于静态数据成员的类内初始化的困惑
【发布时间】:2013-01-10 22:13:15
【问题描述】:

我正在阅读 lippman 的 c++ 入门书,位于 p。 303 他们给这个:

class Account {
private:
  static constexpr int period = 30;
  double daily_tbl[period];
}

如果成员仅在编译器可以替换成员值的上下文中使用,则不需要单独定义初始化的 const 或 constexpr static。但是,如果我们在值不能被替换的上下文中使用该成员,则该成员必须有一个定义。

还有:

例如,如果我们将 Account::period 传递给采用 const int& 的函数,则必须定义 period。

所以我尝试添加这样的功能:

class Account {
private:
  static constexpr int period = 30;
  double daily_tbl[period];

  void foo(const int &i) { ; }
  void bar() { foo(period); } //no error?
};

在那里我添加了一个接受 const int& 的函数。我也没有为周期变量添加任何定义。但我仍然没有得到任何错误,正如他们所说的那样。为什么不呢?

【问题讨论】:

    标签: c++


    【解决方案1】:

    违反此规则不需要诊断。所以行为实际上是未定义的。

    我认为不需要诊断的原因是因为诊断将由链接器给出。并且当编译器优化访问时(就像在这种情况下可能发生的那样),链接器不再注意到任何错误。仍然注意到此错误需要在链接器中进行整个程序分析,以便它可以访问原始未优化的源代码表示。这会增加编译时间并需要高级链接器和编译器。

    【讨论】:

    • 规则定义在哪里?
    • 您能否在回答中详细说明一下?
    • 也许 9.4.2/4 是相关的? “在程序中使用 odr (3.2) 的静态数据成员应该只有一个定义;不需要诊断。”
    • @alok 我认为原因是因为诊断将由链接器给出。并且当编译器优化访问时(就像在他的情况下可能发生的那样),链接器不再注意到任何错误。仍然注意到这个错误需要整个程序分析,这会增加编译时间并需要高级链接器和编译器。
    • 也许这问得太傻了,但为什么要将对 period 分类的 const 引用作为编译器无法替换值的上下文?这是否类似于获取类内初始化静态成员地址的基本原理,这意味着必须将对象放置在某个内存位置而不仅仅是优化?怎么样?
    猜你喜欢
    • 2023-03-18
    • 1970-01-01
    • 2014-09-01
    • 2011-07-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多