Cppcheck is a static analysis tool for C/C++ code. It provides a unique code analysis to detect bugs and focuses on detecting undefined behavior and dangerous coding constructs. The goal is to detect only real errors in the code (i.e. have very few false positives). More information about this tool on the official webpage.
Hint
Cppcheck is rarely wrong about reported errors. But there are many bugs that it doesn’t detect. You will find more bugs in your software by testing your software carefully than by using Cppcheck.
Cppcheck supports a wide variety of static checks that may not be covered by the compiler itself. These checks are static analysis checks that can be performed at a source code level. The program is directed towards static analysis checks that are rigorous, rather than heuristic in nature.
Automatic variable checking
Bounds checking for array overruns
Classes checking (e.g. unused functions, variable initialization, and memory duplication)
Usage of deprecated or superseded functions
Exception safety checking, for example, usage of memory allocation and destructor checks
Memory leaks, e.g. due to lost scope without deallocation
Resource leaks, e.g. due to forgetting to close a file handle
Invalid usage of Standard Template Library functions and idioms
Miscellaneous stylistic and performance errors
Be default Cppcheck is configured to check the next additional defects:
warning
style
performance
portability
unusedFunction
The full list of supported check with detailed description is located on the official webpage.
Cppcheck is implicitly used as the default check tool when check_tool option in “platformio.ini” (Project Configuration File) is not set. To be explicit, you can specify it in the configuration directly:
[env:myenv]
platform = ...
board = ...
check_tool = cppcheck
check_flags = --enable=all
Useful options that can be used used for adjusting check process:
Useful flags that can help more precisely configure Cppcheck to satisfy your project requirements:
Flag
Meaning
--enable=<id>
Enable additional checks. The available ids are:
all
,warning
,style
,performance
,portability
,information
,unusedFunction
,missingInclude
--std=<id>
Set standard. The available options are:
c89
,c99
,c11
,c++03
,c++11
,c++14
,c++17
,c++20 (default)
--language=<language>
Forces Cppcheck to check all files as the given language. Valid values are:
c
,c++
--inline-suppr
Enable inline suppressions. Use them by placing one or more comments, like:
// cppcheck-suppress warningId
on the lines before the warning to suppress (enabled by default if no extra flags specified).
--suppress=<spec>
Suppress warnings that match
<spec>
. The format of<spec>
is:[error id]:[filename]:[line]
--platform=<type>
Specifies platform-specific types and sizes. The available built-in platforms are:
unix32
,unix64
,win32A
,win32W
,win64
,avr8
,native
,unspecified (default)
--inconclusive
Allow reporting defects even though the analysis is inconclusive.
-D<ID>
Define a preprocessor symbol. Example:
-DDEBUG=1
-U<ID>
Undefine preprocessor symbol. Use -U to explicitly hide certain #ifdef <ID> code paths from checking. Example:
-UDEBUG
-I <dir>
Give a path to search for include files. Give several -I parameters to give several paths.
-j <jobs>
Start
<jobs>
threads to do the checking simultaneously.
It might be useful to explicitly instruct Cppcheck to ignore some of the
known defects in project codebase. Since --inline-suppr
is enabled by
default, it’s possible to directly mark pieces of code that will be excluded
from Cppcheck report using // cppcheck-suppress warningId
syntax.
Note
Warning ID can be found in square brackets at the end of defect description, for example:
src\Blink.cpp:17: [low:style] The function 'loop' is never used. [unusedFunction]
By default, PIO Check command doesn’t scan framework sources and that’s
why some functions from in your project might be reported as unused. For example,
you can ignore warnings about setup
and loop
functions from
Arduino-based projects:
// cppcheck-suppress unusedFunction
void setup()
{
...
}
// cppcheck-suppress unusedFunction
void loop()
{
...
}
Cppcheck provides several addon scripts that analyze dump files to check compatibility with secure coding standards and to locate various issues. Most useful addons for verifying compliance with popular guidelines are MISRA and CERT.
MISRA
is a proprietary set of software development guidelines for the
C/C++ programming languages developed by MISRA (Motor Industry Software
Reliability Association). It aims to facilitate code safety, security,
portability, and reliability in the context of embedded systems, specifically
those systems programmed in ISO C/C++.
Note
Since this standard is proprietary, Cppcheck does not display error text
by specifying only the number of violated rules (for example, [c2012-21.3]).
If you want to display full texts for violated rules, you will need to
create a text file containing MISRA rules, which you will have to pass when
calling the script with --rule-texts
flag.
In order to use MISRA
addon you will need to provide a special file with
the description of MISRA
rules. Usually, it has the next contents:
Appendix A Summary of guidelines
Rule 3.1 Required
R3.1 Rule description
Rule 4.1 Required
...
Rule 21.3 Required
R21.3 Rule description
Rule 21.4
R21.4 Rule description
Next, you need to instruct Cppcheck that you want to run an additional
addon script. Since this script requires an additional file with rules,
you can pass it via a special json
file:
{
"script": "addons/misra.py",
"args": ["--rule-texts=misra-rules.txt"]
}
Finally, add new flag to check_flags:
[env:myenv]
platform = ...
board = ...
check_tool = cppcheck
check_flags =
cppcheck: --addon=misra.json
The full list of implemented MISRA
checks can be found on
the official webpage.
SEI CERT
coding standard provides rules for secure coding in the C
programming language. The goal of these rules and recommendations is to
develop safe, reliable, and secure systems, for example by eliminating
undefined behaviors that can lead to undefined program behaviors and
exploitable vulnerabilities.
In order to use the CERT
addon, simply specify it as an additional flag in
check_flags section:
[env:myenv]
platform = ...
board = ...
check_tool = cppcheck
check_flags =
cppcheck: --addon=cert.py