When a class member cannot have a sensible meaning at the moment of construction, I don't initialize it. Obviously that only applies to POD types, you cannot NOT initialize an object with constructors.
The advantage of that, apart from saving CPU cycles initializing something to a value that has no meaning, is that I can detect erroneous usage of these variables with valgrind; which is not possible when I'd just give those variables some random value.
For example,
struct MathProblem {
bool finished;
double answer;
MathProblem() : finished(false) { }
};
Until the math problem is solved (finished) there is no answer. It makes no sense to initialize answer
in advance (to -say- zero) because that might not be the answer. answer
only has a meaning after finished
was set to true.
Usage of answer
before it is initialized is therefore an error and perfectly OK to be UB.
However, a trivial copy of answer
before it is initialized is currently ALSO UB (if I understand the standard correctly), and that doesn't make sense: the default copy and move constructor should simply be able to make a trivial copy (aka, as-if using memcpy), initialized or not: I might want to move this object into a container:
v.push_back(MathProblem());
and then work with the copy inside the container.
Is moving an object with an uninitialized, trivially copyable member indeed defined as UB by the standard? And if so, why? It doesn't seem to make sense.