C++Guns – RoboBlog

06.01.2015

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

Filed under: — Thomas @ 08:01

https://gcc.gnu.org/onlinedocs/gcc/
https://gcc.gnu.org/onlinedocs/libstdc++/manual/debug_mode.html

Hier die Zusammenfassung C&P in eure Projekt Datei

QMAKE_CXXFLAGS_DEBUG += -D_GLIBCXX_DEBUG
QMAKE_CXXFLAGS += -Wpedantic -Wextra -Wvector-operation-performance
QMAKE_CXXFLAGS += -Werror=pedantic -pedantic-errors -Werror=unused-value -Werror=class-memaccess -Werror=overflow
QMAKE_CXXFLAGS += -Werror=narrowing -Werror=return-type -Werror=unused-value -Werror=misleading-indentation -Werror=strict-aliasing -Werror=sign-promo -Werror=dangling-else
QMAKE_CXXFLAGS += -Werror=parentheses -Werror=logical-not-parentheses -Werror=logical-op -Werror=bool-compare -Werror=uninitialized -Werror=maybe-uninitialized
QMAKE_CXXFLAGS += -Werror=unused-result -Werror=reorder -Werror=duplicated-cond -Werror=duplicated-branches -Werror=type-limits -Werror=missing-field-initializers
# lot of work
#QMAKE_CXXFLAGS += -Werror=conversion
# we love pain
#QMAKE_CXXFLAGS += -Werror=shadow

Unabdingbar!!!

-Werror=return-type
Eine vergessene return Anweisung für zu 99% zum segfault.

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

-Werror=uninitialized
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
}

-Werror=unused-value
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
} 

-Werror=missing-field-initializers
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'

-Werror=maybe-uninitialized
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

-Werror=unused-result
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
}

-Werror=narrowing
When you try something not possible.

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

-Werror=misleading-indentation
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...
      a();
      b();                    // ...this statement, but the latter is misleadingly indented as if it were guarded by the 'for'
}

-Werror=strict-aliasing
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

-Werror=sign-promo
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'}

-Werror=dangling-else
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'
  if(false)
    return 0;
  else
    return 1;  

-Werror=parentheses
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

-Werror=logical-not-parentheses
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

-Werror=logical-op
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

-Werror=bool-compare
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

-Werror=implicit-fallthrough=3
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

-Werror=reorder
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
};

-Werror=duplicated-cond
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
    }

-Werror=duplicated-branches
Warn about duplicated conditions in an if-else-if chain.

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

-Werror=type-limits
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=class-memaccess
Warn when the destination of a call to a raw memory function such as memset or memcpy is an object of class type, and when writing into such an object might bypass the class non-trivial or deleted constructor or copy assignment, violate const-correctness or encapsulation, or corrupt virtual table pointers.

struct A {
    A() = default;
    A(A&) { };
};

static_assert( std::is_trivially_copyable<A>::value);  // error: static assertion failed

auto func() {
    A a, b;
    memcpy(&b, &a, sizeof(b)); // error: 'void* memcpy(void*, const void*, size_t)' writing to an object of non-trivially copyable type 'struct A'; use copy-assignment or copy-initialization instead
}

Don't implement constructors for data types. Use the compiler generated ones.

-Werror=padded
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;
};
func():
        movq    .LC0(%rip), %rdx
        movq    %rdi, %rax
        movl    $1, (%rdi)
        movl    $0x40400000, 16(%rdi)
        movq    %rdx, 8(%rdi)
        ret

It create less and hence faster ASM code too.

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

-Werror=shadow
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?

Debug

QMAKE_CXXFLAGS_DEBUG += -D_GLIBCXX_DEBUG
-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

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

-Wconversion
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

-Wvector-operation-performance
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.

-Wdouble-promotion
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.

-Wsuggest-attribute=pure
-Wsuggest-attribute=const
-Wsuggest-attribute=noreturn

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
-fsplit-stack
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