Reputation: 35
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;
struct test
has a non-trivial constructor, this can be checked with:
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?
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
.
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:
Assigning: "t" = "new test", which is allocated but not initialized.
Is Coverity misinterpreting the standard as "value-initialization if trivial constructor OR default-initialization if non-trivial constructor"? If I remove the 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.
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.
Upvotes: 1
Views: 537
Reputation: 1
The warning is not correct for modern C++(including C++17) as explained below.
should I be able to reliably assume that after doing
test *t = new test();
if I immediately checkt->x == nullptr
, that should be true becausechar *x
(a pointer / scalar type) should get zero-initialized during value-initialization of test.
Yes, it is guaranteed by the standard that x
is zero-initialized and hence the check t->x == nullptr
must evaluate to true
. This can be seen from dcl.init#6 which states:
To zero-initialize an object or reference of type T means:
- 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;
(emphasis mine)
Upvotes: 1