Q:

How to initialize a struct of integers to zero?

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{};

A:

From C++11, you may also do:
struct Statistics {
    int counter1 = 0;
    int counter2 = 0;
    // ... more counters here
    int counter100 = 0;
};

A:

Unless you have a fairly specific reason to do otherwise, your first choice should probably be a std::vector, such as:
std::vector<int> Statistics(100);

This will zero all the contents automatically. You can address an individual counter in the array as something like:
++Statistics[40];

...which will increment the 41st item (the first is Statistics[0]).
If the size if really fixed at 100 (or some other number you know at compile time) you might prefer to use std::array instead:
std::array<int, 100> Statistics;

This is potentially a little faster and usually uses a (little) less memory, but fixes the size (whereas with an std::vector you can use push_back, erase, etc., to add and remove items).
Given the edited question (the objects really aren't array-like) I'd probably consider something a little different, probably something like this:
template <class T>
class inited {
    T val;
public:
    inited(T val=T()) : val(val) {}
    operator T() const { return val; }
    operator=(T const &newval) { val = new_val; }
};

struct Statistics { 
    inited<int> sum;
    inited<int> count;
    inited<double> mean;
};

Then an inited<T> is always initialized to some value--you can specify a value if you wish, and if you don't specify any, it uses value initialization (which will give zero for arithmetic types, a null pointer for a pointer type, or use the default constructor for types that define one).
Since it defines an operator T and an operator=, you can still assign to/from elements, just about like usual:
Statistics.sum = 100;
Statistics.count = 2;
Statistics.mean = static_cast<double>(Statistics.sum) / Statistics.count;

You might prefer to use a single:
operator T&() { return val; }

Instead though. This supports both reading and writing (as above) but also compound assignment operators (e.g., += and -=).

A:

Have you considered writing an initializer for each data member?
struct Statistics {
  typedef int counter_t;

  counter_t counter1 = 0;
  counter_t counter2 = 0;
  // ... more counters here
  counter_t counter100 = 0;
};

Note that if you include such initializers, though, the struct is no longer an aggregate, and hence can't be initialized using aggregate initialization via a braced list. Whether that matters or not for this type is hard to say.

