What is the best way to make sure the following large struct always has its integers initialized to 0?
struct Statistics {
int num_queries;
int num_respones;
// ... 97 more counters here
int num_queries_filtered;
}
I would like to avoid having to check each place this struct is initialized to make sure it is value initialized with Statistics s();
rather than default initialized with Statistics s;
.
Statistics s; // Default initialized by accident here
s.num_queries++; // Oh no, this is a bug because it wasn't initialized to zero
Statistics s2{}; // Correctly value initialized
s2.num_queries++; // Successful
Proposal 1 - Use memset
, but this feels like a hack where we take advantage of the value initialization happening to be equivalent to 0 filling the data structure:
struct Statistics {
Statistics() { memset(this, 0, sizeof(*this)); }
// ... counters here
}
Proposal 2 - Use constructor initialization lists, but this is cumbersome and when people add new counters in the future they may forget to zero-initialize them in the constructor:
struct Statistics {
Statistics() : num_queries(0), num_respones(0), /* ... */, num_queries_filtered(0) {}
// ... counters here
}
Proposal 3 - Force the value initialization to take place as follows:
struct StatisticsUnsafe {
// ... counters here
}
struct Statistics : public StatisticsUnsafe {
Statistics() : StatisticsUnsafe() {}
}
What do you feel is the best approach? Do you have other alternatives?
EDIT I want to clarify that in my actual code, each of the counters has a meaningful name, such as "num_queries_received", "num_responses", etc. Which is why I do not opt to use a vector or array of the form "counters[100]"
EDIT2 Changed the example from Statistics s2();
to Statistics s2{};