https://gcc.gnu.org/bugzilla/show_bug.cgi?id=116697

--- Comment #2 from andysem at mail dot ru ---
When we say "uninitialized", we refer to a specific data access, i.e. when a
certain operation uses an object whose value is unspecified as input. With some
stretch, you could consider a mere load of an uninitialized data (e.g. `return
x`, where `x` is uninitialized) worthy of a warning, but that is debatable.

I think, it is not correct to say that `m_buffer` in the original example is
uninitialized. Formally, that object is constructed at the point of the call to
`m_buffer.begin()`, so the object is not uninitialized and the call is valid
and should not emit a warning. I.e. the mere fact of a call of a method on a
constructed object is never an indication of access to uninitialized data. I
believe, the -Wuninitialized warning should not be applicable to objects of
compound types, as long as those objects were constructed, even if the
constructor is trivial.

What is uninitialized are the elements of the `m_buffer.m_buf` array, since
those are objects of a fundamental type that were not initialized on
construction. Access to those objects should emit warnings. But no such access
happens in the example.

To illustrate my point, here's an extended example:

struct array
{
    char m_buf[10];
    unsigned int m_size = 0;

    typedef char* iterator;

    iterator begin() { return m_buf; }
    unsigned int size() const { return m_size; }
    void foo(); // defined in a different TU
    char& operator[](unsigned int i) { return m_buf[i]; }
};

array a;

a.begin(); // should emit no warning as it doesn't access a's members at all
a.size(); // reads m_size that was initialized, so no warning
a.foo(); // it is not known whether foo accesses uninitialized data, no warning
a[1]; // does not access the element of a.m_buf, no warning
char c = a[1]; // reads uninitialized data from a.m_buf, maybe a warning
int n = a[1] + 10; // uses uninitialized data as input, definitely a warning

array b = a; // reads a.m_buf elements that contain uninitialized data,
             // so that may emit a warning; also reads a.m_size which is
             // initialized, and that does not emit a warning

You can see that tracking individual data members, besides being the logical
thing to do, also improve the usefulness of the warning, as the user is alerted
to the specific data members that are missing initialization may be source of
the issue. I.e. in the original example, `m_buffer` is not the problem, its
`m_buffer.m_buf` member would have been, if it was accessed.

Reply via email to