Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Small typo in my initializer list causes unspeakable pain

So, I just got through with a grueling multi-hour debug session of a large server application. The error eventually came down to a barely noticeable typo in a constructor. Basically, it was something like:

template <class T>
class request_handler
{
    public:

    request_handler(T& request, Log& error_log) 
      : m_request(m_request), m_error_log(error_log)
     { 
       /*... some code ... */
     }

    ...
};

See the bug? Well, I didn't. The problem is a small typo in the initializer list: m_request(m_request) is assigning an uninitialized reference to itself. Obviously, it's supposed to read m_request(request).

Now, the member variable m_request is of type T&. So - is there some reason the compiler didn't warn me that I was using an uninitialized variable here?

Using GCC 4.6 with the -Wall flag, if I say:

int x;
x = x;

...it will issue a warning: warning: ‘x’ is used uninitialized in this function [-Wuninitialized]

So, why didn't the compiler warn me when I assigned m_request to itself: essentially assigning an uninitialized reference to itself? It would have saved me hours of annoyance.

like image 308
Channel72 Avatar asked May 21 '12 01:05

Channel72


1 Answers

Annoying bug to track down. It turns out, you don't even need templates to silently fail on this one. This'll do the trick:

class C {
        int a, b;
public:
        C(int t, int z) : a(a), b(z) { };
};

Clang warns on this with -Wuninitialized.

Good news for gcc folks: according to gnu's bugzilla, gcc 4.7.0 has fixed this.

Update

On gcc 4.7.0, add -Wself-init to get this warning (verified by sbellef):

tst.cc: In constructor ‘C::C(int, int)’: tst.cc:4:9: warning: ‘C::a’ is initialized with itself [-Wuninitialized]

like image 73
Chris Betti Avatar answered Nov 15 '22 14:11

Chris Betti