A current list of all implemented of all checks can also be retrieved from the command line application:
# get list of checks cppcheck --doc # get list of error messages cppcheck --errorlist
Check if there is 64-bit portability issues:
- assign address to/from int/long
- casting address from/to integer when returning from function
Warn if there are side effects in assert statements (since this cause different behaviour in debug/release builds).
A pointer to a variable is only valid as long as the variable is in scope.
- returning a pointer to auto or temporary variable
- assigning address of an variable to an effective parameter of a function
- returning reference to local/temporary variable
- returning address of function parameter
- suspicious assignment of pointer argument
- useless assignment of function argument
Boolean type checks
- using increment on boolean
- comparison of a boolean expression with an integer other than 0 or 1
- comparison of a function returning boolean value using relational operator
- comparison of a boolean value with boolean value using relational operator
- using bool in bitwise expression
- pointer addition in condition (either dereference is forgot or pointer overflow is required to make the condition false)
- Assigning bool value to pointer or float
Check for invalid usage of Boost:
- container modification during BOOST_FOREACH
Out of bounds checking:
- Array index out of bounds detection by value flow analysis
- Dangerous usage of strncat()
- char constant passed as size to function like memset()
- strncpy() leaving string unterminated
- Accessing array with negative index
- Unsafe usage of main(argv, argc) arguments
- Accessing array with index variable before checking its value
- Check for large enough arrays being passed to functions
- Allocating memory with a negative size
Check function usage:
- return value of certain functions not used
- invalid input values for functions
- Warn if a function is called whose usage is discouraged
Check the code for each class.
- Missing constructors and copy constructors
- Constructors which should be explicit
- Are all variables initialized by the constructors?
- Are all variables assigned by 'operator='?
- Warn if memset, memcpy etc are used on a class
- Warn if memory for classes is allocated with malloc()
- If it's a base class, check that the destructor is virtual
- Are there unused private functions?
- 'operator=' should return reference to self
- 'operator=' should check for assignment to self
- Constness for member functions
- Order of initializations
- Suggest usage of initialization list
- Initialization of a member with itself
- Suspicious subtraction from 'this'
- Call of pure virtual function in constructor/destructor
- Duplicated inherited data members
Match conditions with assignments and other conditions:
- Mismatching assignment and comparison => comparison is always true/false
- Mismatching lhs and rhs in comparison => comparison is always true/false
- Detect usage of | where & should be used
- Detect matching 'if' and 'else if' conditions
- Mismatching bitand (a &= 0xf0; a &= 1; => a = 0)
- Find dead code which is inaccessible due to the counter-conditions check in nested if statements
- Condition that is always true/false
- Mutual exclusion over || always evaluating to true
- Comparisons of modulo results that are always true/false.
- Known variable values => condition is always true/false
- Invalid test for overflow (for example 'ptr+u < ptr'). Condition is always false unless there is overflow, and overflow is UB.
Checking exception safety
- Throwing exceptions in destructors
- Throwing exception during invalid state
- Throwing a copy of a caught exception instead of rethrowing the original exception
- Exception caught by value instead of by reference
- Throwing exception in noexcept, nothrow(), attribute((nothrow)) or __declspec(nothrow) function
- Unhandled exception specification when calling function foo()
Check format string input/output operations.
- Bad usage of the function 'sprintf' (overlapping data)
- Missing or wrong width specifiers in 'scanf' format string
- Use a file that has been closed
- File input/output without positioning results in undefined behaviour
- Read to a file that has only been opened for writing (or vice versa)
- Repositioning operation on a file opened in append mode
- Using fflush() on an input stream
- Invalid usage of output stream. For example: 'std::cout << std::cout;'
- Wrong number of arguments given to 'printf' or 'scanf;'
Detect when a auto variable is allocated but not deallocated or deallocated twice.
Not taking the address to allocated memory
If the constructor allocate memory then the destructor must deallocate it.
Is there any allocated memory when a function goes out of scope
Don't forget to deallocate struct members
- null pointer dereferencing
- undefined null pointer arithmetic
- division with zero
- scoped object destroyed immediately after construction
- assignment in an assert statement
- free() or delete of an invalid memory location
- bitwise operation with negative right operand
- provide wrong dimensioned array to pipe() system command (--std=posix)
- cast the return values of getc(),fgetc() and getchar() to character and compare it to EOF
- race condition with non-interlocked access after InterlockedDecrement() call
- expression 'x = x++;' depends on order of evaluation of side effects
- either division by zero or useless condition
- memset() with a value out of range as the 2nd parameter
- access of moved or forwarded variable.
- redundant data copying for const variable
- subsequent assignment or copying to a variable or buffer
- passing parameter by value
- memset() with a float as the 2nd parameter
- Passing NULL pointer to function with variable number of arguments leads to UB.
- C-style pointer cast in C++ code
- casting between incompatible pointer types
- Incomplete statement
- check how signed char variables are used
- variable scope can be limited
- unusual pointer arithmetic. For example: "abc" + 'd'
- redundant assignment, increment, or bitwise operation in a switch statement
- redundant strcpy in a switch statement
- Suspicious case labels in switch()
- assignment of a variable to itself
- Comparison of values leading always to true or false
- Clarify calculation with parentheses
- suspicious comparison of '\0' with a char variable
- duplicate break statement
- unreachable code
- testing if unsigned variable is negative/positive
- Suspicious use of ; at the end of 'if/for/while' statement.
- Array filled incompletely using memset/memcpy/memmove.
- NaN (not a number) value used in arithmetic expression.
- comma in return statement (the comma can easily be misread as a semicolon).
- prefer erfc, expm1 or log1p to avoid loss of precision.
- identical code in both branches of if/else or ternary operator.
- redundant pointer operation on pointer like &some_ptr.
- find unused 'goto' labels.
Check for invalid usage of STL:
- out of bounds errors
- misuse of iterators when iterating through a container
- mismatching containers in calls
- dereferencing an erased iterator
- for vectors: using iterator/pointer after push_back has been used
- optimisation: use empty() instead of size() to guarantee fast code
- suspicious condition when using find
- redundant condition
- common mistakes when using string::c_str()
- using auto pointer (auto_ptr)
- useless calls of string and STL functions
- dereferencing an invalid iterator
- reading from empty STL container
sizeof() usage checks
- sizeof for array given as function argument
- sizeof for numeric given as function argument
- using sizeof(pointer) instead of the size of pointed data
- look for 'sizeof sizeof ..'
- look for calculations inside sizeof()
- look for suspicious calculations with sizeof()
- using 'sizeof(void)' which is undefined
Detect misusage of C-style strings:
- overlapping buffers passed to sprintf as source and destination
- incorrect length arguments for 'substr' and 'strncmp'
- suspicious condition (runtime comparison of string literals)
- suspicious condition (string literals as boolean)
- suspicious comparison of a string literal with a char variable
- suspicious comparison of '\0' with a char variable
- bitwise shift by too many bits (only enabled when --platform is used)
- signed integer overflow (only enabled when --platform is used)
- dangerous sign conversion, when signed value can be negative
- possible loss of information when assigning int result to long variable
- possible loss of information when returning int result as long return value
- float conversion overflow
- using uninitialized local variables
- using allocated data before it has been initialized
- using dead pointer
Check for functions that are never called
- unused variable
- allocated but unused variable
- unred variable
- unassigned variable
- unused struct member
Warn if using postfix operators ++ or -- rather than prefix operator
Check for misusage of variable argument lists:
- Wrong parameter passed to va_start()
- Reference passed to va_start()
- Missing va_end()
- Using va_list before it is opened
- Subsequent calls to va_start/va_copy()