【问题标题】:Must I initialize function-local static consts?我必须初始化函数局部静态常量吗?
【发布时间】:2020-04-30 07:31:34
【问题描述】:

我正在使用 MS Visual Studio 2017, V. 15.9.8。

我正在使用出色的 JetBrains ReSharper Ultimate 2019.1.2 Build 191.0.20190603.142841。它在指定位置给我一个警告:

#include <vector>
struct T
{
  std::vector<char> m;
  const char *f() const
  {
    static const char emptyData;         // ReSharper complains here
    return m.size() ? &m[0] : &emptyData;
  }
};

消息是

file.h: 'const unsigned char' 类型的静态局部变量应该被初始化。这是非标准的 Microsoft C++ 扩展。

如果 emptyData 不是 const,警告就会消失。

警告是错误的,因为所有静态数据,包括常量静态局部变量,都是按照标准零初始化的,对吧?

【问题讨论】:

    标签: c++ static initialization constants default-value


    【解决方案1】:

    警告是错误的,因为所有静态数据,包括常量静态局部变量,都是按照标准零初始化的,对吗?

    这有点不准确。确实存在初始零初始化,但之后变量被默认初始化。对于char,默认初始化是不初始化,如果之前的零初始化将保持零值不变。一个迂腐的正确消息是常量对象(这种类型的)不能被默认初始化。

    标准(最新草案说):

    如果程序要求对 const 限定类型 T 的对象进行默认初始化,则 T 应为 const-default-constructible 类类型或其数组。

    程序违反了这条规则,格式不正确。

    请注意,在 C++17 之前,任何 const 限定类型都不允许默认初始化。

    【讨论】:

    • 虽然考虑到非常量字符完全可以在没有显式初始化的情况下使用,但这种对字符的限制似乎很奇怪。我想该标准希望通过将它们归零来防止用户创建未正确初始化的对象(毕竟,如果它们是常量,则不能“修复”它们,而不是非常量)。但是委员会(这是正确的)不想添加另一个拜占庭式的细节,以便说“......除非这是一个对零初始化非常满意的 POD”。
    • @Peter-ReinstateMonica 是的,据我所知,语言可以允许对零初始化的 const 对象进行默认初始化,但它就是不允许。事实上,我认为这是因为他们不希望针对此类利基用例再增加一条规则的复杂性。
    【解决方案2】:

    我相信是因为const,常量变量必须被初始化,如果行是const char emptyData;,你会得到一个未初始化的错误constvariable,所以我认为这不是static修饰符导致问题。

    关于这件事有一个话题似乎很有趣here

    无论是const static char emptyData;还是static const char emptyData;g++2a(GNU)编译器中的错误是:

    错误:未初始化的 'const emptyData' [-fpermissive]

    【讨论】:

    • 嗯...我明白你的论点了。是的,通常需要初始化 const,静态 const 也不例外 - 可以说 const 在静态之前被考虑。
    • @Peter-ReinstateMonica 可能,但编译器错误是关于 const 而不是 static
    猜你喜欢
    • 2018-02-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-07-21
    • 1970-01-01
    • 2013-01-03
    相关资源
    最近更新 更多