I was refreshing my understanding of value-initialisation versus default-initialisation, and came across this:
struct C {
int x;
int y;
C () { }
};
int main () {
C c = C ();
}
Apparently this is UB because
In the case of C(), there is a constructor that is capable of
initializing the x and y members, so no initialization takes place.
Attempting to copy C() to c therefore results in undefined behavior.
I think I understand why, but I’m not certain. Can someone please elaborate?
Does that mean this is also UB?
int x; x = x;
Incidentally, with regards to value initialisation, is the following guaranteed to be zero?
int x = int ();
Your first example has undefined behavior because the default, compiler
generated copy constructor will do a memberwise copy,
ints may havetrapping values, and reading a trapping value to copy it may cause the
program to crash.
In practice, I can’t imagine this ever actually crashing; the compiler
will almost certainly optimize the copy out, and even if it didn’t, it
would likely use some special bitwise copy which would copy without
checking for trapping values. (In C++, you are guaranteed to be able to
copy bytes.)
For the second case, again, undefined behavior. Although in this case,
you have assignment rather than copy construction, and the compiler is
less likely to optimize it away. (There is no assignment in your first
example, only copy construction.)
For the third, yes. An initializer with an empty parenthese (and no
user defined default initializer to override it) first performs zero
initialization (exactly as occurs for variables with static lifetime).