C++Guns – RoboBlog blogging the bot


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

Filed under: — Thomas @ 08:01

Check cache size cat /sys/devices/system/cpu/cpu0/cache/index3/size or lstopo



Hier die Zusammenfassung C&P in eure Projekt Datei. Mit GCC Version Test

GCC_VERSION = $$system($$QMAKE_CXX " -dumpversion")

contains(VERSION_MAJ, 12) {
message( "g++ version 12.x found" )
CONFIG += g++12
contains(VERSION_MAJ, 11) {
message( "g++ version 11.x found" )
CONFIG += g++11
contains(VERSION_MAJ, 10) {
message( "g++ version 10.x found" )
CONFIG += g++10
contains(VERSION_MAJ, 9) {
message( "g++ version 9.x found" )
CONFIG += g++9
contains(VERSION_MAJ, 8) {
message( "g++ version 8.x found" )
CONFIG += g++8
contains(VERSION_MAJ, 7) {
message( "g++ version 7.x found" )
CONFIG += g++7
contains(VERSION_MAJ, 6) {
message( "g++ version 6.x found" )
CONFIG += g++6
contains(VERSION_MAJ, 5) {
message( "g++ version 5.x found" )
CONFIG += g++5
contains(VERSION_MAJ, 4) {
message( "g++ version 4.x found" )
CONFIG += g++4

g++8|g++9|g++10|g++11|g++12: QMAKE_CXXFLAGS += -Werror=class-memaccess
g++9|g++10|g++11|g++12: QMAKE_CXXFLAGS += -Werror=init-list-lifetime -Werror=redundant-move -Werror=pessimizing-move -Werror=class-conversion
g++10|g++11|g++12: QMAKE_CXXFLAGS += -Werror=comma-subscript
g++11|g++12: QMAKE_CXXFLAGS += -Werror=range-loop-construct -Werror=deprecated-enum-enum-conversion -Werror=deprecated-enum-float-conversion -Werror=mismatched-new-delete -Werror=vexing-parse
g++12: QMAKE_CXXFLAGS += -Werror=missing-requires -Werror=int-in-bool-context -Werror=bidi-chars=any -Werror=array-compare

QMAKE_CXXFLAGS += -Wpedantic -Werror=extra -Wno-error=sign-compare -Wno-error=unused-parameter
QMAKE_CXXFLAGS += -Wvector-operation-performance -Werror=div-by-zero -Werror=multichar -Werror=switch -Werror=switch-enum -Werror=switch-bool -Werror=switch-unreachable
QMAKE_CXXFLAGS += -Werror=pedantic -pedantic-errors -Werror=unused-value -Werror=overflow -Werror=address -Werror=tautological-compare
QMAKE_CXXFLAGS += -Werror=narrowing -Werror=return-type -Werror=misleading-indentation -Werror=strict-aliasing -Werror=sign-promo
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
QMAKE_CXXFLAGS += -Werror=return-local-addr -Werror=sequence-point -Werror=dangling-else -Werror=conversion-null -Werror=empty-body -Werror=ignored-qualifiers -Werror=null-dereference
# lot of work
# QMAKE_CXXFLAGS += -Werror=conversion
# we love pain
# QMAKE_CXXFLAGS += -Werror=shadow

# The QT library is not free of warnings. If we enable e.g. -Wconversion we see a lot
# of warnings from Qt we cant fix nor care. Here is a simple way to disable warnings
# for external framwork. Just include library headers using -isystem instead of -I.
# This will make them "system headers" and GCC won't report warnings for them.
# This still trigger some warnings due to inline of code.
# If a standard system include directory, or a directory specified with -isystem, is also specified with -I, the -I option is ignored.


TODO -Werror=range-loop-construct -Werror=deprecated-enum-enum-conversion -Werror=deprecated-enum-float-conversion -Werror=mismatched-new-delete -Werror=vexing-parse
TODO GCC12 -Wno-missing-requires -Wint-in-bool-context -Wbidi-chars=[none|unpaired|any|ucn] -Warray-compare


struct A { };

struct B {
    B(A) {};

struct C {
    C(const A& a)
    : b(B(a)) // error: a temporary bound to 'C::b' only persists until the constructor exits

    const B& b; // Do not store references


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

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

Lokale Konstanten als const referenzen zurückgeben führt leider zum sefault;

const int& func() {
    return 0; // error: returning reference to temporary

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 about uses of a comma expression within a subscripting expression. This usage was deprecated in C++20. However

auto func(std::vector<int> v, int i, int j) {  
  return v[i,j];                               //  error: top-level comma expression in array subscript is deprecated

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 about suspicious uses of memory addresses, e.g. comparisons against the memory address of a string literal.

if(g->name == "quad")   // error: comparison with string literal results in unspecified behavior

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

Error 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

Error 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 whenever a switch statement has an index of enumerated type and lacks a case for one or more of the named codes of that enumeration. (The presence of a default label prevents this warning.)

error: enumeration value 'unknown' not handled in switch

See next.

The only difference between -Wswitch and this option is that this option gives a warning about an omitted enumeration code even if there is a default label.

Warn whenever a switch statement has an index of boolean type and the case values are outside the range of a boolean type

auto func(int type) {
    switch (type==4) {  // error: switch condition has boolean value
        case 2:;

Warn whenever a switch statement contains statements between the controlling expression and the first case label, which will never be executed.

auto func(int type) {
    switch (type) {
        int i = 0;   // note:   crosses initialization of 'int i'
        case 2:;     // error: jump to case label
                     // error: statement will never be executed

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;

Error 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

Error if a self-comparison always evaluates to true or false, or about bitwise comparisons that always evaluate to true or false.

auto func(int i) {
  return i >= i;  //  error: self-comparison always evaluates to true


if(1==2);  // error: suggest braces around empty body in an 'if' statement


const int func() {  // error: type qualifiers ignored on function return type
    return 42;

Error about code that may have undefined semantics because of violations of sequence point rules in the C and C++ standards. There is more to read in the GCC manual.

auto func(int i) {
  return i++ + ++i;  //  error: operation on 'i' may be undefined 

Error on compile-time integer division by zero. Floating-point division by zero is not warned about.

  while(pos_nextRecord /= 0) { // error: division by zero [-Werror=div-by-zero]

Error if a multicharacter constant (‘'FOOF'’) is used.

  std::cout << ' kB\n';  // error: multi-character character constant

Error about the case when a conversion function will never be called.

struct U {};

struct T : U { 
  operator T() { // error: converting 'T' to the same type will never use a type conversion operator

  operator U() { // errro  converting 'T' to a base class 'U' will never use a type conversion operator
  operator void() { // error: converting 'T' to 'void' will never use a type conversion operator


int func() {
    return NULL; // error converting to non-pointer type 'int' from NULL

Error about redundant calls to std::move.

T fn(T t) {
  return std::move(t); // error: redundant move in return statement

Error when a call to std::move prevents copy elision.

T fn() {
  T t;
  return std::move(t); // error: moving a local object in a return statement prevents copy elision

Error about uses of std::initializer_list that are likely to result in dangling pointers.

// initializer_list underlying array’s lifetime ends at the end of the return statement
auto func1() {
  std::initializer_list<int> li = { 1,2,3 }; 
  return li;  // error: returning local initializer_list variable 'li' does not extend the lifetime of the underlying array

// li's initial underlying array lives as long as li
// assignment changes li to point to a temporary array
auto func2() {
  std::initializer_list<int> li = { 1,2,3 };
  li = { 4, 5 }; // error: assignment from temporary initializer_list does not extend the lifetime of the underlying array

// When a list constructor stores the begin pointer from the initializer_list argument, this doesn’t extend the lifetime of the array. 
// so if a class variable is constructed from a temporary initializer_list,
// the pointer is left dangling by the end of the variable declaration statement. 
struct A {
  A(std::initializer_list<int> li) 
  : p(li.begin()) // error: initializing 'A::p' from 'std::initializer_list<int>::begin' does not extend the lifetime of the underlying array

  const int* p;

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.


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;

auto func() {
    return X{1, 2.0, 3.0};
        movq    .LC0(%rip), %rdx
        movq    %rdi, %rax
        movl    $1, (%rdi)
        movl    $0x40400000, 16(%rdi)
        movq    %rdx, 8(%rdi)

Swap the double with the float. 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?


Warn if the compiler detects paths that trigger erroneous or undefined behavior due to dereferencing a null pointer.


Warn about the case when an exception handler is shadowed by another handler, which can point out a wrong ordering of exception handlers

int main() {
  try {
  catch(std::exception& ex) {     // note: for type ‘std::exception’
  catch(std::logic_error& ex) {   // error: exception of type ‘std::logic_error’ will be caught by earlier handler 



Warn about catch handlers that do not catch via reference.
With -Wcatch-value=1 (or -Wcatch-value for short) warn about polymorphic class types that are caught by value.
With -Wcatch-value=2 warn about all class types that are caught by value.
With -Wcatch-value=3 warn about all types that are not caught by reference. This might be overkill, because catching a "const char*" is then an error.

 try {
 catch(std::system_error ex) { //  error: catching polymorphic type ‘class std::system_error’ by value
 catch(std::error_code) { //  error: catching type ‘class std::error_code’ by value
 catch(int) {  // error: catching non-reference type ‘int’


Wenn du verzweifelst:
-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