Thanks for preparing the wiki page. I have looked at the examples from this slide: http://ecn.channel9.msdn.com/events/GoingNative12/GN12Clang.pdf with trunk gcc. In some cases, gcc's warning matches that of clang but in majority of cases, gcc either emits no warnings or worse ones. The warnings in the comments are from clang. One possible advantage of clang is that adding new warnings is relatively easier.
Another side note. This slide mentioned two things: 1) thread-safety static check; 2) compiler based dynamic check. The first one was first introduced in a gcc branch but never made into the mainline, but now it is getting into Clang. 2) Gcc work on dynamic check was also done partially, but not made into trunk either. Gcc command line option: -fsyntax-only -Wall -std=c++11 thanks, David Example 1: Gcc produces nothing even with -Warray-bounds -------------------------------------------------------------------------------- int foo() { int arr[100]; // ... return arr[100]; } /* array.cpp:4:10: warning: array index 100 is past the end of the array (which contains 100 elements) [-Warray-bounds] return arr[100]; ^ ~~~ array.cpp:2:3: note: array 'arr' declared here int arr[100]; ^ 1 warning generated. */ Example 2: gcc produces nothing even with -Warray-bounds -------------------------------------------------------------------------------- constexpr int arr_size = 42; constexpr int N = 44; void f(int); int test() { int arr[arr_size]; // ... f(arr[N]); // ... if (N < arr_size) return arr[N]; return 0; } /* deadcode.cpp:7:5: warning: array index 44 is past the end of the array (which contains 42 elements) [-Warray-bounds] f(arr[N]); ^ ~ deadcode.cpp:5:3: note: array 'arr' declared here int arr[arr_size]; ^ 1 warning generated. */ Example 3: nothing from gcc: --------------------------------------- #include <memory.h> struct S { int a, b, c; float vec[16]; }; void test(S *s) { // ... memset(s, 0, sizeof(s)); // ... } /* memset.cpp:5:23: warning: argument to 'sizeof' in 'memset' call is the same expression as the destination; did you mean to dereference it? [- Wsizeof-pointer-memaccess] memset(s, 0, sizeof(s)); ~ ^ 1 warning generated. */ Example 4: Nothing from gcc: ---------------------------------------- static const long long DiskCacheSize = 8 << 30; // 8 Gigs /* overflow.cpp:1:42: warning: signed shift result (0x200000000) requires 35 bits to represent, but 'int' only has 32 bits [-Wshift-overflow] static const long long DiskCacheSize = 8 << 30; // 8 Gigs ~ ^ ~~ 1 warning generated. */ Example 5: More suggestions from clang --> suggesting changing = to == ------------------------------------------------------------------------------------------------- void foo(); void bar(); void test(int i) { // ... if (i = 42) foo(); else bar(); } /* parentheses1.cpp:5:9: warning: using the result of an assignment as a condition without parentheses [-Wparentheses] if (i = 42) foo(); ~~^~~~ parentheses1.cpp:5:9: note: place parentheses around the assignment to silence this warning if (i = 42) foo(); ^ ( ) parentheses1.cpp:5:9: note: use '==' to turn this assignment into an equality comparison if (i = 42) foo(); ^ == 1 warning generated. */ Example 6: Nothing from gcc ------------------------------------------- int get(); void test() { int i = get(); // ... if ((i == get())) { // ... } } /* parentheses2.cpp:5:10: warning: equality comparison with extraneous parentheses [-Wparentheses-equality] if ((i == get())) { ~~^~~~~~~~ parentheses2.cpp:5:10: note: remove extraneous parentheses around the comparison to silence this warning if ((i == get())) { ~ ^ ~ parentheses2.cpp:5:10: note: use '=' to turn this equality comparison into an assignment if ((i == get())) { ^~ = 1 warning generated. */ Example 7: Nothing from gcc ---------------------------------------- int test(bool b, int x, int y) { return 42 + b ? x : y; } /* parentheses4.cpp:2:17: warning: operator '?:' has lower precedence than '+'; '+' will be evaluated first [-Wparentheses] return 42 + b ? x : y; ~~~~~~ ^ parentheses4.cpp:2:17: note: place parentheses around the '+' expression to silence this warning return 42 + b ? x : y; ^ ( ) parentheses4.cpp:2:17: note: place parentheses around the '?:' expression to evaluate it first return 42 + b ? x : y; ^ ( ) 1 warning generated. */ Example 8: No useful suggestions for corrections from gcc: ----------------------------------------------------------------------------- struct BaseType {}; struct DerivedType : public BaseType { static int base_type; DerivedType() : basetype() {} }; /* typo1.cpp:4:19: error: initializer 'basetype' does not name a non-static data member or base class; did you mean the base class 'BaseType'? DerivedType() : basetype() {} ^~~~~~~~ BaseType typo1.cpp:2:22: note: base class 'BaseType' specified here struct DerivedType : public BaseType { ^~~~~~~~~~~~~~~ 1 error generated. */ Example 9: Same as example 8: --------------------------------------------- namespace fiz { namespace bang { int foobar(); } } int test() { return bang::Foobar(); } /* typo2.cpp:5:10: error: use of undeclared identifier 'bang'; did you mean 'fiz::bang'? return bang::Foobar(); ^~~~ fiz::bang typo2.cpp:1:27: note: 'fiz::bang' declared here namespace fiz { namespace bang { ^ typo2.cpp:5:16: error: no member named 'Foobar' in namespace 'fiz::bang'; did you mean 'foobar'? return bang::Foobar(); ~~~~~~^~~~~~ foobar typo2.cpp:2:7: note: 'foobar' declared here int foobar(); ^ 2 errors generated. */ Example 10: nothing from gcc: ------------------------------------------ struct S { int n; }; S bar(); S test() { S foo, bar(); // ... return foo; } /* conversions.cppreturn.cpvexing.cpp vexing.cpp:5:6: warning: empty parentheses interpreted as a function declaration [-Wvexing-parse] bar(); ^~ vexing.cpp:4:8: note: change this ',' to a ';' to call 'bar' S foo, ^ ; vexing.cpp:5:6: note: replace parentheses with an initializer to declare a variable bar(); ^~ {} 1 warning generated. */ Example 11: nothing from gcc: ----------------------------------------- int test(int i) { if (i > 42); return 42; return i; } /* emptyif.cpp:2:14: warning: if statement has empty body [-Wempty-body] if (i > 42); ^ 1 warning generated. */ Example 12: Worse source information for MACRO in gcc: ----------------------------------------------------------------------------- #define M1(x, y, z) y(); #define M2(x, y, z) M1(x, y, z) void test() { M2(a, b, c); } /* ===== Clang macros1.cpp:4:9: error: use of undeclared identifier 'b' M2(a, b, c); ^ macros1.cpp:2:27: note: expanded from macro 'M2' #define M2(x, y, z) M1(x, y, z) ^ macros1.cpp:1:21: note: expanded from macro 'M1' #define M1(x, y, z) y(); ^ 1 error generated. ================ */ Example 13: nothing from gcc: --------------------------------------- template <class T, class U> struct S {}; template <typename... Ts> void f(Ts...); template <typename... Ts> struct X { template <typename... Us> void g() { f(S<Ts, Us>()...); } }; void test(X<int, float> x) { x.g<int, float, double>(); } /* oscar-wilde.cpp:6:18: error: pack expansion contains parameter packs 'Ts' and 'Us' that have different lengths (2 vs. 3) f(S<Ts, Us>()...); ~~ ~~ ^ oscar-wilde.cpp:11:5: note: in instantiation of function template specialization 'X<int, float>::g<int, float, double>' requested here x.g<int, float, double>(); ^ 1 error generated. */ Example 14: Nothing from gcc: template <int N> struct S1 { int arr[N - 5]; }; template <typename T> struct S2 { S1<sizeof(T)> s1; }; template <typename T> void foo(T x) { S2<T> s2; } void test() { foo(42); } /* From Clang: templates1.cpp:1:38: error: 'arr' declared as an array with a negative size template <int N> struct S1 { int arr[N - 5]; }; ^~~~~ templates1.cpp:2:49: note: in instantiation of template class 'S1<4>' requested here template <typename T> struct S2 { S1<sizeof(T)> s1; }; ^ templates1.cpp:3:45: note: in instantiation of template class 'S2<int>' requested here template <typename T> void foo(T x) { S2<T> s2; } ^ templates1.cpp:4:15: note: in instantiation of function template specialization 'foo<int>' requested here void test() { foo(42); } ============================================== */ On Thu, Apr 12, 2012 at 12:43 PM, Jonathan Wakely <jwakely....@gmail.com> wrote: > On 12 April 2012 11:41, Jonathan Wakely wrote: >> Two more examples, then I'll save it for a wiki page instead of the >> mailing list: > > And here it is: > > http://gcc.gnu.org/wiki/ClangDiagnosticsComparison