clang++
does not ever allow default initialization of a const variable of class-type without a user-defined constructor; g++
is slightly less restrictive (see below). According to this answer, this is because POD types "are not initialized by default." If I understand correctly, this means that default-initialization does not invoke the default-constructor, nor does it invoke value-initialization, so the data members inside the POD type are not initialized. Of course it makes no sense to have a const POD type with uninitialized values in it, since they can never be initialized and therefore are not safe to use.
There are a few variants of this situation:
clang++
does not treat this as a special case, nor, I think, does the standard, but g++
does allow it, even when the constructor is marked explicit
.){}
. (This is the recommended workaround on the clang
page describing the issue.)=default
. (C++11 onward; the type is still considered POD, so neither compiler nor the standard treat it as a special case.){}
, which (if I understand correctly) becomes value-initialization. (C++11 onward; both compilers—and, I think, the standard—allow this.)In the first case, there can be no uninitialized members, so it's unclear why any instantiation of the class itself would ever be considered "uninitialized," regardless of whether or not it's const
. Since g++
allows this behavior, is it safe to use? Why is it prohibited by clang++
and the standard? (And are there any other cases where g++
allows POD-default-initialization where clang++
does not?)
In the second and third cases, the requirement of using {}
instead of =default
seems odd to me. EDIT: this question explains the difference quite well, so I've removed the part of the question asking about the distinction. (I still think it's a terribly confusing aspect of the language, though.)
Finally, will Foo f{}
always zero-initialize members of built-in type if Foo::Foo(void)
is {}
, =default
, or implicitly-declared?
Since g++ allows this behavior, is it safe to use?
Safe in what sense? It's obviously not portable currently. However, it's not going to give you unexpected results on g++.
Why is it prohibited by clang++ and the standard?
Presumably the committee either didn't think about it when they put the "user-provided constructor required" rule in C++98, or decided that special-casing empty POD classes isn't worth the specification complexity; clang++ is just following the standard. However, the standard is likely going to change to more generally allow you to write const Foo f;
as long as the constructor will, in fact, initialize every subobject.
Finally, will
Foo f{};
always zero-initialize members of built-in type ifFoo::Foo(void)
is{}
,=default
, or implicitly-declared?
Yes for the latter two. No for the first. That one counts as user-provided, so value-initialization doesn't perform zero-initialization before calling the default constructor.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With