Clang (3.6.0) ignores warnings from included header files

366 views Asked by At

It seems that clang is ignoring warnings which occur in included header files:

// what.hpp
class What {
public:
    What() {
        int x = x;
    }
};

// main.cpp
#include <iostream>
#include "what.hpp"
int main()
{
    int y = y;
    std::cout << "y is: " << y << std::endl;
    What w;
}

Compiling this with g++ (4.9.2) gives:

$ g++ -dumpversion && g++ -Wall -Wextra main.cpp -o main
4.9.2
In file included from main.cpp:3:0:
what.hpp: In constructor ‘What::What()’:
what.hpp:5:17: warning: ‘x’ is used uninitialized in this function [-Wuninitialized]
     int x = x;
             ^
main.cpp: In function ‘int main()’:
main.cpp:5:13: warning: ‘y’ is used uninitialized in this function [-Wuninitialized]
 int y = y;

Compiling the same thing with clang:

$ clang++ --version && clang++ -Wall -Wextra main.cpp -o main
Ubuntu clang version 3.6.0-2ubuntu1~trusty1 (tags/RELEASE_360/final) (based on LLVM 3.6.0)
Target: x86_64-pc-linux-gnu
Thread model: posix
main.cpp:5:13: warning: variable 'y' is uninitialized when used within its own initialization [-Wuninitialized]
int y = y;
    ~   ^
1 warning generated.

I'm not sure, If I'm using clang wrong or if this is indeed a bug? Any hints? Thanks in advance.

2

There are 2 answers

2
Shafik Yaghmour On BEST ANSWER

This is not clang bug, the warning is being suppressed because x is subsequently unused, the bug report I cite below explains the rationale behind this behavior.

In this specific case it is considered a clang feature to not to produce this warning(Wuninitialized) if the variable is otherwise unused, although most will probably find this surprising behavior.

We can see the rationale from the following bug report: No uninitialized warning for self-initialization (e.g., int x = x):

Right, this is deliberate, and is considered to be a feature rather than a bug. We suppress the warning on 'int x = x;' only in the case where 'x' is otherwise unused.

It is mentioned in the bug report that self-intialization in this way is:

considered the canonical way to suppress "use of uninitialized variable" warnings

This does not depend on whether the code in question is included from a header, I put together a live example that shows the warning does not show up when the code is all in one file.

Note, initializing a variable in this way:

int x = x;

is undefined behavior, for reference see:

So in general we can not have any expectations as to the result and the compiler is not obligated to issue a diagnostic although doing so can be helpful.

0
Barry On

The lines in question are syntactically correct. Neither are particularly useful lines of code - both exhibit undefined behavior - but they're legal C++ code. As such, the compiler is not obligated to issue any diagnostic.

This is just a quality of implementation issue - the compiler isn't obligated to issue warnings in this case, but it's very helpful when it does. As to why clang happens to warn only for y and not for x, whereas gcc warns for both - I am not sure. It definitely has nothing to do with included header files (you can see for yourself by just defining What in main.cpp) and likely has to do with the fact that you're printing y and never reading from x again.

But you can't rely on complete accuracy with these warnings. When you get them, however, they're always worth paying attention to.