This does appear to be a bug in MSVC. In all three cases wrapper
has no user-provided default constructor, so initialization with wrapper()
invokes:
(All citations from n3690)
(8.5/11) An object whose initializer is an empty set of parentheses, i.e., (), shall be value-initialized.
(thanks to dyp), this will result in zero-intialization of int v
Initialization then refers us to the rule:
(8.5/8) 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.
The zero initialization rules state:
(8.5/6) if T is a (possibly cv-qualified) non-union class type, each non-static data member and each base-class subobject is zero-initialized and padding is initialized to zero bits
int v
being a data member of wrapper
is zero initialiazed itself according to:
(8.5/6) if T is a scalar type (3.9), the object is initialized to the value obtained by converting the integer literal 0 (zero) to T
Which is not the behavior you observe.
= default
would be when there are no other constructors present, which seems pointless... – Sams=default
is going to give back the default constructor, butv
is unintialized in both cases. With gcc I get 0 even in the first case, but it's all just by chance. – Carbreywrapper() { }
(i.e. avoid initializingv
)? (Don't forget to do both of these experiments in debug mode with no optimizations.) – Sams= default
gives you the same default constructor that would've been implicitly declared if the user hadn't declared any constructors, but feel free to correct me if I'm wrong. – Sams