简体   繁体   English

在具有默认非平凡构造函数的结构上使用值初始化时,结构标量成员是否被零初始化

[英]Are struct scalar members zero-initialized when using value-initialization on a struct with a default non-trivial-constructor

If I have the following struct如果我有以下结构

struct test
{
    char *x;
    std::string y;
};

And I initialize with我用

test *t = new test();

That should value-initialize the object and do the following based on the standard:这应该值初始化对象并根据标准执行以下操作:

if T is a (possibly cv-qualified) class type without a user-provided or deleted default constructor, then the object is zero-initialized and the semantic constraints for default-initialization are checked, and if T has a non-trivial default constructor, the object is default-initialized;如果 T 是没有用户提供或删除的默认构造函数的(可能是 cv 限定的)类类型,则该对象被零初始化并检查默认初始化的语义约束,并且如果 T 具有非平凡的默认构造函数, 对象是默认初始化的;

struct test has a non-trivial constructor, this can be checked with: struct test有一个非平凡的构造函数,可以通过以下方式检查:

static_assert(std::is_trivially_constructible<test>::value, "test is not is_trivially_constructible");`)

Does the standard imply that my test object should always be zero-initialized in the case of value-initialization, and then subsequently default-initialized?标准是否暗示我的test对象在值初始化的情况下应始终为零初始化,然后默认初始化?

And should I be able to reliably assume that after doing test *t = new test() if I immediately check t->x == nullptr , that should be true because char *x (a pointer / scalar type) should get zero-initialized during value-initialization of test .我是否应该能够可靠地假设在执行test *t = new test()之后,如果我立即检查t->x == nullptr ,那应该是正确的,因为char *x (指针/标量类型)应该为零-在test的值初始化期间初始化。

I ask because Coverity gives a Type: Uninitialized pointer read (UNINIT) warning because it reports the following if you try do something like if (t->x) after value-intialization:我之所以问是因为 Coverity 给出了一个Type: Uninitialized pointer read (UNINIT)警告,因为如果您在值初始化后尝试执行类似if (t->x)的操作,它会报告以下内容:

Assigning: "t" = "new test", which is allocated but not initialized.赋值:"t" = "new test",已分配但未初始化。

Is Coverity misinterpreting the standard as "value-initialization if trivial constructor OR default-initialization if non-trivial constructor"? Coverity 是否将标准误解为“如果是平凡的构造函数则为值初始化,或者如果为非平凡的构造函数则为默认初始化”? If I remove the std::string y;如果我删除std::string y; member so that test has a trivial-default-constructor, Coverity no longer has a warning and assumes the char *x member is zero-initialized.成员,因此test有一个普通的默认构造函数,Coverity 不再有警告并假设char *x成员是零初始化的。

For what it's worth, I'm just using g++ -O3 -std=c++17 to compile and I have not been able to create an actual scenario where zero-intialization doesn't happen for my test object.对于它的价值,我只是使用g++ -O3 -std=c++17进行编译,并且我无法创建一个实际场景,其中我的test对象不会发生零初始化。

The warning is not correct for modern C++(including C++17) as explained below.该警告不适用于现代 C++(包括 C++17),如下所述。

should I be able to reliably assume that after doing test *t = new test();我是否应该能够可靠地假设在完成test *t = new test(); if I immediately check t->x == nullptr , that should be true because char *x (a pointer / scalar type) should get zero-initialized during value-initialization of test.如果我立即检查t->x == nullptr ,那应该是正确的,因为char *x (指针/标量类型)应该在测试的值初始化期间进行零初始化。

Yes, it is guaranteed by the standard that x is zero-initialized and hence the check t->x == nullptr must evaluate to true .是的,标准保证x是零初始化的,因此检查t->x == nullptr必须评估为true This can be seen from dcl.init#6 which states:这可以从dcl.init#6中看出:

To zero-initialize an object or reference of type T means:对 T 类型的对象或引用进行零初始化意味着:

  • if T is a (possibly cv-qualified) non-union class type, its padding bits are initialized to zero bits and each non-static data member , each non-virtual base class subobject, and, if the object is not a base class subobject, each virtual base class subobject is zero-initialized ;如果 T 是(可能是 cv 限定的)非联合类类型,则其填充位初始化为零位,并且每个非静态数据成员、每个非虚拟基类子对象,并且如果对象不是基类子对象,每个虚拟基类子对象都是零初始化的

(emphasis mine) (强调我的)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 为什么在堆中创建对象或堆栈中的临时对象时,隐式构造函数对结构中的POD进行零初始化? - Why is a POD in a struct zero-initialized by an implicit constructor when creating an object in the heap or a temporary object in the stack? 清除类型为“struct”的 object,而无需进行简单的复制分配; 改用赋值或值初始化 - clearing an object of type 'struct ' with no trivial copy-assignment; use assignment or value-initialization instead 为什么将值初始化指定为不调用平凡的默认构造函数? - Why is value-initialization specified as not calling trivial default constructors? 获取默认初始化(NOT值/零初始化)POD作为右值 - Get a default-initialized (NOT value/zero-initialized) POD as an rvalue struct 成员默认初始化的区别 - Difference in default initialization of struct members 具有非平凡构造函数的“不可变”结构 - “immutable” struct with non-trivial constructor 结构中成员的默认值 - Default value of members in a struct 使用默认的默认构造函数进行C ++ 11值初始化 - C++11 value-initialization with defaulted default constructor 为什么 FILE* 指针在 C++ 的默认初始化中初始化为零? - Why is a FILE* pointer zero-initialized in C++'s default initialization? 默认情况下,C++ 结构的成员是否初始化为 0? - Are members of a C++ struct initialized to 0 by default?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM