为啥 std::string 零初始化为不确定值

Posted

技术标签:

【中文标题】为啥 std::string 零初始化为不确定值【英文标题】:why std::string is zero initialized to indeterminate value为什么 std::string 零初始化为不确定值 【发布时间】:2014-09-09 08:58:46 【问题描述】:

以下代码示例来自 cppreference: http://en.cppreference.com/w/cpp/language/zero_initialization

#include <string>

double f[3]; // zero-initialized to three 0.0's
int* p;   // zero-initialized to null pointer value
std::string s; // zero-initialized to indeterminate value
               // then default-initialized to ""
int main(int argc, char* argv[])

    static int n = argc; // zero-initialized to 0
                         // then copy-initialized to argc
    delete p; // safe to delete a null pointer

它说 std::string 是零初始化为 indeterminate 值。同一页还说,对于非联合类类型,所有非静态成员都初始化为零。

在不知道 std::string 的实现细节的情况下,我认为它有一个 char* 的成员来存储实际的字符串值。如果是这样的话,char*不应该被零初始化为空指针吗,如果是,那么为什么这个值是不确定的?

【问题讨论】:

(1) std::string 不需要有char* 成员; (2) 即使有一个,std::string 也可能包含其他未指定类型和语义的未指定数据成员。 “不知道实现细节”——完全正确。它们没有被指定,所以没有办法说零初始化是否给出了一个有效的对象。 谢谢,但你能举个例子,什么类型在零初始化时会有未指定的数据。我对“零”部分有点困惑,根据标准,所有标量类型零都从整数零转换,指针设置为空,等等。 @swang:谁说的未指定数据?正如您所说,构成对象内部表示的任何标量类型的值都已明确指定;但没有构造函数来建立有效状态,这可能会或可能不会给出有效的string 对象,因此该对象的值不确定。 当您说未指定时,我只是在评论上述内容。我明白零初始化的 std::string 不可用/无效,只是希望标准或 cppreference 可以更清楚地说明它。他们确实提到使用默认初始化的不确定的非类类型值是未定义的行为,但没有提到零初始化的不确定类类型。价值。 【参考方案1】:

基本成分是零初始化的,但对于std::string,这些零值意味着的含义完全取决于实现。

动态初始化调用std::string构造函数并建立类不变量(关于实例内部状态的基本假设)。

只有在此之后才是保证对象可用的值。

【讨论】:

@vz0:请查看标准中处理静态变量初始化的部分。在动态初始化之前,无论类型如何,它们都被零初始化。显然在 C++11 中是 §3.6.2。抱歉,我没有太多时间。 @vz0:是的。在静态初始化期间,在动态初始化开始之前,所有非局部变量都被初始化为零。引用 C++11 3.6.2/2:“具有静态存储持续时间的变量或线程存储持续时间应在任何其他初始化发生之前进行零初始化。”跨度> 所以基本上即使是静态 const std::string 也是零初始化的,在调用构造函数之前它仍然不可用?这意味着我不能在静态初始化阶段使用 statc const std::string,但如果它是 const char* ,我可以? @swang:基本上是的。但要注意静态初始化顺序惨败

以上是关于为啥 std::string 零初始化为不确定值的主要内容,如果未能解决你的问题,请参考以下文章

为啥 int 数组在 C++ 中未初始化为零?

为啥我的内核的共享内存似乎初始化为零?

为啥 g++ 不关心初始化列表分配给 (const std::string&) a (std::string)?和其他怪异[关闭]

为未初始化的std :: string变量分配了多少内存?

std::string 浮动或加倍

零初始化、静态初始化和值初始化有何不同?