This question is related to another post of mine: why allocate_shared and make_shared so slow
In here I can describe the question more clearly.
Think about t
A a(t...);
Will be parsed as initializing a
with t...
.† When t...
is empty, as when you call it, this will be understood as value-initializing a
.
For A
without a user-provided default constructor, value-initialize is to zero all its members, hence the memset
.
When you provide a constructor for A
, value-initialize is to call the default constructor, which you defined to be do nothing, therefore no memset
will be called.
This is not a bug in the compiler, this is required behaviour. To remove the redundant memset
, you could just write A a;
. In this case a
is default-initialized and no automatic zeroing occurs, with or without the user-provided constructor.
† This is important since A a()
will be parsed as a function called a
with return type A
Doesn't this explain it?
We can see that:
Zero initialization is performed [...] as part of value-initialization sequence for [...] members of value-initialized class types that have no constructors, including value initialization of elements of aggregates for which no initializers are provided.
...
Value initialization is performed [...] when a non-static data member or a base class is initialized using a member initializer with an empty pair of parentheses or braces (since C++11);
So putting a_()
in the member initializer list falls into the latter case, that as a result invokes zero initialization of the array.
To answer your question: to me this seems to be a standard behavior not a compiler bug.