C++Guns – RoboBlog


GNU compiler collection - Useful GCC warning/errors not enabled by Wall Wextra

Filed under: — Thomas @ 08:01



Eine vergessene return Anweisung für zu 99% zum segfault.

int func() {   
// error: no return statement in function returning non-void

Error if an automatic variable is used without first being initialized.

auto func()  {
    double X;
    return X; // error: 'X' is used uninitialized in this function

Warn whenever a statement computes a result that is explicitly not used. This includes an expression-statement or the left-hand side of a comma expression that contains no side effects.

auto func(std::vector<int> v, int i, int j) {  
  return v[i,j];                               //  error: left operand of comma operator has no effect

Warn if a structure’s initializer has some fields missing.

struct X {    
  int a,b,c; 
X x{1, 2};    // error: missing initializer for member 'X::c'

For an automatic (i.e. local) variable, if there exists a path from the function entry to a use of the variable that is initialized, but there exist some other paths for which the variable is not initialized, the compiler emits a warning if it cannot prove the uninitialized paths are not executed at run time.

    double T=0, dt;
    for (double t=0; t<T; t+=dt) { } // error: 'dt' may be used uninitialized in this function

Error if a caller of a function does not use its return value / if the return value is discarded.

[[nodiscard]] int bar(int);
auto foo() {
    bar(3); // error: ignoring return value of 'int bar(int)', declared with attribute nodiscard

When you try something not possible.

int func(double a) {
    return {a};    //  error: narrowing conversion of 'a' from 'double' to 'int' inside { } 

Error when the indentation of the code does not reflect the block structure.

void a();
void b();
void func() {   
    for(int i=0; i < 10; ++i) //  error: this 'for' clause does not guard...
      b();                    // ...this statement, but the latter is misleadingly indented as if it were guarded by the 'for'

Error about code that might break the strict aliasing rules that the compiler is using for optimization.

int i=0;
float f = *reinterpret_cast<float*>(&i); // error: dereferencing type-punned pointer will break strict-aliasing rule
i = *(int*)&f;                               // error: dereferencing type-punned pointer will break strict-aliasing rule

Error when overload resolution chooses a promotion from unsigned or enumerated type to a signed type, over a conversion to an unsigned type of the same size.
A function with a signed parameter is called with a unsigned argument, instead of the function with an unsigned parameter.

void func(int32_t);
void func(uint32_t);
func(uint8_t()); // error: passing 'uint8_t' {aka 'unsigned char'} chooses 'int32_t' {aka 'int'} over 'uint32_t' {aka 'unsigned int'}
func(int8_t()); // ok
func(uint16_t()); // error: passing 'uint16_t' {aka 'short unsigned int'} chooses 'int32_t' {aka 'int'} over 'uint32_t' {aka 'unsigned int'}
enum noClassEnum { A };
func(e); // error: passing 'noClassEnum' chooses 'int32_t' {aka 'int'} over 'uint32_t' {aka 'unsigned int'}

Error about constructions where there may be confusion to which if statement an else branch belongs.

if(true)       // error: suggest explicit braces to avoid ambiguous 'else'
    return 0;
    return 1;  

Error if parentheses are omitted in certain contexts, such as when there is an assignment in a context where a truth value is expected, or when operators are nested whose precedence people often get confused about. ^

int (a);          // error: unnecessary parentheses in declaration of 'a'
if(a = 1)         // error: suggest parentheses around assignment used as truth value

Error about logical not used on the left hand side operand of a comparison.

if(!a == 1)   // error: logical not is only applied to the left hand side of comparison
              // note: add parentheses around left hand side expression

Warn about suspicious uses of logical operators in expressions. This includes using logical operators in contexts where a bit-wise operator is likely to be expected. Also warns when the operands of a logical operator are the same:

    if((a && 0b10) or (a && 0b10)) {} // error: logical 'and' applied to non-boolean constant
                                      // error: logical 'or' of equal expressions

Warn about boolean expression compared with an integer value different from true/false

 return (x > 0) == 2;    //   error: comparison of constant '2' with boolean expression is always false

Error when a switch case falls through.
C++17 provides a standard way to suppress error using [[fallthrough]]; attribute.

error: this statement may fall through

Warn when the order of member initializers given in the code does not match the order in which they must be executed.

struct A {
  int i;
  int j;                 // error: 'A::j' will be initialized after 'int A::i'
  A(): j (0), i (1) { }  // error: when initialized here

Warn about duplicated conditions in an if-else-if chain.

    if(a == 0) {          // note: previously used here
    } else if (a == 0) {  // error: duplicated 'if' condition

Warn about duplicated conditions in an if-else-if chain.

    if(a == 0) {     // error: this condition has identical branches
        return 1;
    } else  {
        return 1;

Warn if a comparison is always true or always false due to the limited range of the data type.

auto func(unsigned int x) {
  return x >= 0;    // error: comparison of unsigned expression >= 0 is always true

-Werror=padded errr no
Warn if padding is included in a structure, either to align an element of the structure or to align the whole structure.

struct X {    // error: padding struct size to alignment boundary
  int i;  
  double d;   // error: padding struct to align 'X::d'
  float j;
        movq    .LC0(%rip), %rdx
        movq    %rdi, %rax
        movl    $1, (%rdi)
        movl    $0x40400000, 16(%rdi)
        movq    %rdx, 8(%rdi)

It create less and hence faster ASM code too.

struct X {    
  int i;  
  float j;
  double d;  
        movsd   .LC0(%rip), %xmm0
        movabsq $4611686018427387905, %rax

Warn whenever a local variable or type declaration shadows another variable, parameter, type, class member, or whenever a built-in function is shadowed.
This IS a good thing. See C++ Guns: -Wshadow for constructor arguments

struct A{
    int i;         // note: shadowed declaration is here
    auto func() {
        int i;     // error: declaration of 'i' shadows a member of 'A'

-Werror=pedantic -pedantic-errors
Issue all the warnings demanded by strict ISO C and ISO C++; reject all programs that use forbidden extensions, and some other programs that do not follow ISO C and ISO C++

struct A {
};;         // error: extra ';'

Y0u als0 pay @tt3nti0n to t43 sp311ing rul3s. Do YOU?


-fsignaling-nans -fsanitize-undefined-trap-on-error -fsanitize=undefined,address -fsanitize=float-divide-by-zero -ffpe-trap=invalid,zero,overflow

Some usefull compiler warnings which are not enabled by -Wall or -Wextra

Warn if a function that is declared as inline cannot be inlined.

Warn for implicit conversions that may alter a value. This includes conversions between real and integer, like abs (x) when x is double; conversions between signed and unsigned, like unsigned ui = -1; and conversions to smaller types, like sqrtf (M_PI). also warn for confusing overload resolution for user-defined conversions

Warn if vector operation is not implemented via SIMD capabilities of the architecture. Mainly useful for the performance tuning. Vector operation can be implemented piecewise, which means that the scalar operation is performed on every vector element; in parallel, which means that the vector operation is implemented using scalars of wider type, which normally is more performance efficient; and as a single scalar, which means that vector fits into a scalar type.

-Weffc++ (C++ and Objective-C++ only)
Warn about violations of the following style guidelines from Scott Meyers' Effective C++ series of books:

Define a copy constructor and an assignment operator for classes with dynamically-allocated memory.
Prefer initialization to assignment in constructors.
Have operator= return a reference to *this.
Don't try to return a reference when you must return an object.
Distinguish between prefix and postfix forms of increment and decrement operators.
Never overload &&, ||, or ,.

This option also enables -Wnon-virtual-dtor, which is also one of the effective C++ recommendations. However, the check is extended to warn about the lack of virtual destructor in accessible non-polymorphic bases classes too.

When selecting this option, be aware that the standard library headers do not obey all of these guidelines; use ‘grep -v’ to filter out those warnings.

Give a warning when a value of type float is implicitly promoted to double. CPUs with a 32-bit “single-precision” floating-point unit implement float in hardware, but emulate double in software. On such a machine, doing computations using double values is much more expensive because of the overhead required for software emulation.


Warn about functions that might be candidates for attributes pure, const or noreturn. The compiler only warns for functions visible in other compilation units or (in the case of pure and const) if it cannot prove that the function returns normally. A function returns normally if it doesn't contain an infinite loop or return abnormally by throwing, calling abort() or trapping. This analysis requires option -fipa-pure-const, which is enabled by default at -O and higher. Higher optimization levels improve the accuracy of the analysis.

Other Stuff
Generate code to automatically split the stack before it overflows. The resulting program has a discontiguous stack which can only overflow if the program is unable to allocate any more memory. This is most useful when running threaded programs, as it is no longer necessary to calculate a good stack size to use for each thread. This is currently only implemented for the i386 and x86_64 back ends running GNU/Linux.

When code compiled with -fsplit-stack calls code compiled without -fsplit-stack, there may not be much stack space available for the latter code to run. If compiling all code, including library code, with -fsplit-stack is not an option, then the linker can fix up these calls so that the code compiled without -fsplit-stack always has a large stack. Support for this is implemented in the gold linker in GNU binutils release 2.21 and later.

No Comments

No comments yet.

RSS feed for comments on this post.

Sorry, the comment form is closed at this time.

Powered by WordPress