693 lines
22 KiB
XML
693 lines
22 KiB
XML
<?xml version="1.0" encoding="UTF-8"?>
|
|
<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.4//EN"
|
|
"http://www.oasis-open.org/docbook/xml/4.4/docbookx.dtd">
|
|
<book>
|
|
<bookinfo>
|
|
<title>Cppcheck 1.52</title>
|
|
|
|
<date>2011-10-07</date>
|
|
</bookinfo>
|
|
|
|
<chapter>
|
|
<title>Introduction</title>
|
|
|
|
<para>Cppcheck is an analysis tool for C/C++ code. Unlike C/C++ compilers
|
|
and many other analysis tools, it doesn't detect syntax errors. Cppcheck
|
|
only detects the types of bugs that the compilers normally fail to detect.
|
|
The goal is no false positives.</para>
|
|
|
|
<para>Supported code and platforms:</para>
|
|
|
|
<itemizedlist>
|
|
<listitem>
|
|
<para>You can check non-standard code that includes various compiler
|
|
extensions, inline assembly code, etc.</para>
|
|
</listitem>
|
|
|
|
<listitem>
|
|
<para>Cppcheck should be compilable by any C++ compiler that handles
|
|
the latest C++ standard.</para>
|
|
</listitem>
|
|
|
|
<listitem>
|
|
<para>Cppcheck should work on any platform that has sufficient CPU and
|
|
memory.</para>
|
|
</listitem>
|
|
</itemizedlist>
|
|
|
|
<para>Accuracy</para>
|
|
|
|
<para>Please understand that there are limits of Cppcheck. Cppcheck is
|
|
rarely wrong about reported errors. But there are many bugs that it
|
|
doesn't detect.</para>
|
|
|
|
<para>You will find more bugs in your software by testing your software
|
|
carefully, than by using Cppcheck. You will find more bugs in your
|
|
software by instrumenting your software, than by using Cppcheck. But
|
|
Cppcheck can still detect some of the bugs that you miss when testing and
|
|
instrumenting your software.</para>
|
|
</chapter>
|
|
|
|
<chapter>
|
|
<title>Getting started</title>
|
|
|
|
<section>
|
|
<title>First test</title>
|
|
|
|
<para>Here is a simple code</para>
|
|
|
|
<programlisting>int main()
|
|
{
|
|
char a[10];
|
|
a[10] = 0;
|
|
return 0;
|
|
}</programlisting>
|
|
|
|
<para>If you save that into <filename>file1.c</filename> and
|
|
execute:</para>
|
|
|
|
<programlisting>cppcheck file1.c</programlisting>
|
|
|
|
<para>The output from cppcheck will then be:</para>
|
|
|
|
<programlisting>Checking file1.c...
|
|
[file1.c:4]: (error) Array 'a[10]' index 10 out of bounds</programlisting>
|
|
</section>
|
|
|
|
<section>
|
|
<title>Checking all files in a folder</title>
|
|
|
|
<para>Normally a program has many source files. And you want to check
|
|
them all. Cppcheck can check all source files in a directory:</para>
|
|
|
|
<programlisting>cppcheck path</programlisting>
|
|
|
|
<para>If "path" is a folder then cppcheck will check all source files in
|
|
this folder.</para>
|
|
|
|
<programlisting>Checking path/file1.cpp...
|
|
1/2 files checked 50% done
|
|
Checking path/file2.cpp...
|
|
2/2 files checked 100% done</programlisting>
|
|
</section>
|
|
|
|
<section>
|
|
<title>Excluding a file or folder from checking</title>
|
|
|
|
<para>To exclude a file or folder, there are two options.</para>
|
|
|
|
<para>The first option is to only provide the paths and files you want
|
|
to check.</para>
|
|
|
|
<programlisting>cppcheck src/a src/b</programlisting>
|
|
|
|
<para>All files under <filename class="directory">src/a</filename> and
|
|
<filename class="directory">src/b</filename> are then checked.</para>
|
|
|
|
<para>The second option is to use <parameter class="command">-i</parameter>,
|
|
with it you specify files/paths to ignore. With this command no files in
|
|
<filename class="directory">src/c</filename> are checked:</para>
|
|
|
|
<programlisting>cppcheck -isrc/c src</programlisting>
|
|
</section>
|
|
|
|
<section>
|
|
<title>Severities</title>
|
|
|
|
<para>The possible severities for messages are:</para>
|
|
|
|
<variablelist>
|
|
<varlistentry>
|
|
<term>error</term>
|
|
|
|
<listitem>
|
|
<para>used when bugs are found</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
|
|
<varlistentry>
|
|
<term>warning</term>
|
|
|
|
<listitem>
|
|
<para>suggestions about defensive programming to prevent
|
|
bugs</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
|
|
<varlistentry>
|
|
<term>style</term>
|
|
|
|
<listitem>
|
|
<para>stylistic issues related to code cleanup (unused functions,
|
|
redundant code, constness, and such)</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
|
|
<varlistentry>
|
|
<term>performance</term>
|
|
|
|
<listitem>
|
|
<para>suggestions for making the code faster</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
|
|
<varlistentry>
|
|
<term>portability</term>
|
|
|
|
<listitem>
|
|
<para>portability warnings. 64-bit portability. code might work different on different compilers. etc.</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
|
|
<varlistentry>
|
|
<term>information</term>
|
|
|
|
<listitem>
|
|
<para>Informational messages that might be interesting. Ignore
|
|
these messages unless you really agree.</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
</variablelist>
|
|
|
|
<remark>The performance messages are based on 'common knowledge'. It is
|
|
not certain that fixing performance messages will make any measurable
|
|
difference in speed. Fixing performance messages generally doesn't make
|
|
your code more readable.</remark>
|
|
</section>
|
|
|
|
<section>
|
|
<title>Enable messages</title>
|
|
|
|
<para>By default only <parameter class="command">error</parameter> messages
|
|
are shown. Through the <parameter class="command">--enable</parameter>
|
|
command more checks can be enabled.</para>
|
|
|
|
<section>
|
|
<title>Stylistic issues</title>
|
|
|
|
<para>With <parameter class="command">--enable=style</parameter> you
|
|
enable most <parameter class="command">warning</parameter>,
|
|
<parameter class="command">style</parameter> and
|
|
<parameter class="command">performance</parameter> messages.</para>
|
|
|
|
<para>Here is a simple code example:</para>
|
|
|
|
<programlisting>void f(int x)
|
|
{
|
|
int i;
|
|
if (x == 0)
|
|
{
|
|
i = 0;
|
|
}
|
|
}</programlisting>
|
|
|
|
<para>There are no bugs in that code so Cppcheck won't report anything
|
|
by default. To enable the stylistic messages, use the
|
|
<parameter class="command">--enable=style</parameter> command:</para>
|
|
|
|
<programlisting>cppcheck --enable=style file3.c</programlisting>
|
|
|
|
<para>The output from Cppcheck is now:</para>
|
|
|
|
<programlisting>Checking file3.c...
|
|
[file3.c:3]: (style) Variable 'i' is assigned a value that is never used
|
|
[file3.c:3]: (style) The scope of the variable i can be reduced</programlisting>
|
|
</section>
|
|
|
|
<section>
|
|
<title>Unused functions</title>
|
|
|
|
<para>This check will try to find unused functions. It is best to use
|
|
this when the whole program is checked, so that all usages is seen by
|
|
cppcheck.</para>
|
|
|
|
<programlisting>cppcheck --enable=unusedFunction path</programlisting>
|
|
</section>
|
|
|
|
<section>
|
|
<title>Enable all checks</title>
|
|
|
|
<para>To enable all checks your can use the
|
|
<parameter class="command">--enable=all</parameter> flag:</para>
|
|
|
|
<programlisting>cppcheck --enable=all path</programlisting>
|
|
</section>
|
|
</section>
|
|
|
|
<section>
|
|
<title>Saving results in file</title>
|
|
|
|
<para>Many times you will want to save the results in a file. You can
|
|
use the normal shell redirection for piping error output to a
|
|
file.</para>
|
|
|
|
<programlisting>cppcheck file1.c 2> err.txt</programlisting>
|
|
</section>
|
|
|
|
<section>
|
|
<title>Multithreaded checking</title>
|
|
|
|
<para>The command line client can only use threads in posix
|
|
environments. But it is the goal to be able to use threads on all
|
|
platforms.</para>
|
|
|
|
<para>The option -j is used to specify the number of threads you want to use.
|
|
For example, to use 4 threads to check the files in a folder:</para>
|
|
|
|
<programlisting>cppcheck -j 4 path</programlisting>
|
|
</section>
|
|
</chapter>
|
|
|
|
<chapter id="preprocessor-configurations">
|
|
<title>Preprocessor configurations</title>
|
|
|
|
<para>By default Cppcheck will check all preprocessor configurations
|
|
(except those that has #error in them). This is the recommended
|
|
behaviour.</para>
|
|
|
|
<para>But if you want to manually limit the checking you can do so with
|
|
<parameter class="command">-D</parameter>.</para>
|
|
|
|
<para>Beware that only the macros, which are given here and the macros
|
|
defined in source files and known header files are considered. That
|
|
excludes all the macros defined in some system header files, which are by
|
|
default not examined by Cppcheck.</para>
|
|
|
|
<para>The usage: if you, for example, want to limit the checking so the
|
|
only configuration to check should be <literal>DEBUG=1;__cplusplus</literal>
|
|
then something like this can be used:</para>
|
|
|
|
<programlisting>cppcheck -DDEBUG=1 -D__cplusplus path</programlisting>
|
|
</chapter>
|
|
|
|
<chapter>
|
|
<title>XML output</title>
|
|
|
|
<para>Cppcheck can generate the output in XML format.</para>
|
|
|
|
<para>Use the <parameter class="command">--xml</parameter> flag when you
|
|
execute cppcheck:</para>
|
|
|
|
<programlisting>cppcheck --xml file1.cpp</programlisting>
|
|
|
|
<para>The XML format is:</para>
|
|
|
|
<programlisting><?xml version="1.0"?>
|
|
<results>
|
|
<error file="file1.cpp" line="123" id="someError"
|
|
severity="error" msg="some error text"/>
|
|
</results></programlisting>
|
|
|
|
<para>Attributes:</para>
|
|
|
|
<variablelist>
|
|
<varlistentry>
|
|
<term><sgmltag class="attribute">file</sgmltag></term>
|
|
|
|
<listitem>
|
|
<para>filename. Both relative and absolute paths are possible</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
|
|
<varlistentry>
|
|
<term><sgmltag class="attribute">line</sgmltag></term>
|
|
|
|
<listitem>
|
|
<para>a number</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
|
|
<varlistentry>
|
|
<term><sgmltag class="attribute">id</sgmltag></term>
|
|
|
|
<listitem>
|
|
<para>id of error. These are always valid symbolnames.</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
|
|
<varlistentry>
|
|
<term><sgmltag class="attribute">severity</sgmltag></term>
|
|
|
|
<listitem>
|
|
<para>either <sgmltag class="attvalue">error</sgmltag> or
|
|
<sgmltag class="attvalue">style</sgmltag>.</para>
|
|
<para><literal>warning</literal> and <literal>performance</literal>
|
|
are saved as <sgmltag class="attvalue">style</sgmltag>.</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
|
|
<varlistentry>
|
|
<term><sgmltag class="attribute">msg</sgmltag></term>
|
|
|
|
<listitem>
|
|
<para>the error message</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
</variablelist>
|
|
</chapter>
|
|
|
|
<chapter>
|
|
<title>Reformatting the output</title>
|
|
|
|
<para>If you want to reformat the output so it looks different you can use
|
|
templates.</para>
|
|
|
|
<para>To get Visual Studio compatible output you can use
|
|
<parameter class="command">--template=vs</parameter>:</para>
|
|
|
|
<programlisting>cppcheck --template=vs gui/test.cpp</programlisting>
|
|
|
|
<para>This output will look like this:</para>
|
|
|
|
<programlisting>Checking gui/test.cpp...
|
|
gui/test.cpp(31): error: Memory leak: b
|
|
gui/test.cpp(16): error: Mismatching allocation and deallocation: k</programlisting>
|
|
|
|
<para>To get gcc compatible output you can use
|
|
<parameter class="command">--template=gcc</parameter>:</para>
|
|
|
|
<programlisting>cppcheck --template=gcc gui/test.cpp</programlisting>
|
|
|
|
<para>The output will look like this:</para>
|
|
|
|
<programlisting>Checking gui/test.cpp...
|
|
gui/test.cpp:31: error: Memory leak: b
|
|
gui/test.cpp:16: error: Mismatching allocation and deallocation: k</programlisting>
|
|
|
|
<para>You can write your own pattern (for example a comma-separated
|
|
format):</para>
|
|
|
|
<programlisting>cppcheck --template="{file},{line},{severity},{id},{message}" gui/test.cpp</programlisting>
|
|
|
|
<para>The output will look like this:</para>
|
|
|
|
<programlisting>Checking gui/test.cpp...
|
|
gui/test.cpp,31,error,memleak,Memory leak: b
|
|
gui/test.cpp,16,error,mismatchAllocDealloc,Mismatching allocation and deallocation: k</programlisting>
|
|
</chapter>
|
|
|
|
<chapter>
|
|
<title>Suppressions</title>
|
|
|
|
<para>If you want to filter out certain errors you can suppress
|
|
these.</para>
|
|
|
|
<section>
|
|
<title>Suppressing a certain error type</title>
|
|
|
|
<para>You can suppress certain types of errors. The format for such a
|
|
suppression is one of:</para>
|
|
|
|
<programlisting>[error id]:[filename]:[line]
|
|
[error id]:[filename2]
|
|
[error id]</programlisting>
|
|
|
|
<para>The <replaceable>error id</replaceable> is the id that you want to
|
|
suppress. The easiest way to get it is to use the <parameter
|
|
class="command">--xml</parameter> command line flag. Copy and paste the
|
|
<replaceable>id</replaceable> string from the XML output. This may be
|
|
<literal>*</literal> to suppress all warnings (for a specified file or
|
|
files).</para>
|
|
|
|
<para>The <replaceable>filename</replaceable> may include the wildcard
|
|
characters <literal>*</literal> or <literal>?</literal>, which match any
|
|
sequence of characters or any single character respectively. It is
|
|
recommended that you use "/" as path separator on all operating
|
|
systems.</para>
|
|
|
|
<section>
|
|
<title>Command line suppression</title>
|
|
|
|
<para>The <parameter class="command">--suppress=</parameter> command
|
|
line option is used to specify suppressions on the command line.
|
|
Example:</para>
|
|
|
|
<programlisting>cppcheck --suppress=memleak:src/file1.cpp src/</programlisting>
|
|
</section>
|
|
|
|
<section>
|
|
<title>Listing suppressions in a file</title>
|
|
|
|
<para>You can create a suppressions file. Example:</para>
|
|
|
|
<programlisting>// suppress memleak and exceptNew errors in the file src/file1.cpp
|
|
memleak:src/file1.cpp
|
|
exceptNew:src/file1.cpp
|
|
|
|
// suppress all uninitvar errors in all files
|
|
uninitvar</programlisting>
|
|
|
|
<para>Note that you may add empty lines and comments in the
|
|
suppressions file.</para>
|
|
|
|
<para>You can use the suppressions file like this:</para>
|
|
|
|
<programlisting>cppcheck --suppressions suppressions.txt src/</programlisting>
|
|
</section>
|
|
</section>
|
|
|
|
<section>
|
|
<title>Inline suppressions</title>
|
|
|
|
<para>Suppressions can also be added directly in the code by adding
|
|
comments that contain special keywords. Before adding such comments,
|
|
consider that the code readability is sacrificed a little.</para>
|
|
|
|
<para>This code will normally generate an error message:</para>
|
|
|
|
<programlisting>void f() {
|
|
char arr[5];
|
|
arr[10] = 0;
|
|
}</programlisting>
|
|
|
|
<para>The output is:</para>
|
|
|
|
<programlisting># cppcheck test.c
|
|
Checking test.c...
|
|
[test.c:3]: (error) Array 'arr[5]' index 10 out of bounds</programlisting>
|
|
|
|
<para>To suppress the error message, a comment can be added:</para>
|
|
|
|
<programlisting>void f() {
|
|
char arr[5];
|
|
|
|
// cppcheck-suppress arrayIndexOutOfBounds
|
|
arr[10] = 0;
|
|
}</programlisting>
|
|
|
|
<para>Now the --inline-suppr flag can be used to suppress the warning.
|
|
No error is reported when invoking cppcheck this way:</para>
|
|
|
|
<programlisting>cppcheck --inline-suppr test.c</programlisting>
|
|
</section>
|
|
</chapter>
|
|
|
|
<chapter>
|
|
<title>Leaks</title>
|
|
|
|
<para>Looking for memory leaks and resource leaks is a key feature of
|
|
Cppcheck. Cppcheck can detect many common mistakes by default. But through
|
|
some tweaking you can improve the checking.</para>
|
|
|
|
<section>
|
|
<title>User-defined allocation/deallocation functions</title>
|
|
|
|
<para>Cppcheck understands many common allocation and
|
|
deallocation functions. But not all.</para>
|
|
|
|
<para>Here is example code that might leak memory or resources:</para>
|
|
|
|
<programlisting>void foo(int x)
|
|
{
|
|
void *f = CreateFred();
|
|
if (x == 1)
|
|
return;
|
|
DestroyFred(f);
|
|
}</programlisting>
|
|
|
|
<para>If you analyse that with Cppcheck it won't find any leaks:</para>
|
|
|
|
<programlisting>cppcheck --enable=possibleError fred1.cpp</programlisting>
|
|
|
|
<para>You can add some custom leaks checking by providing simple
|
|
implementations for the allocation and deallocation functions. Write
|
|
this in a separate file:</para>
|
|
|
|
<programlisting>void *CreateFred()
|
|
{
|
|
return malloc(100);
|
|
}
|
|
|
|
void DestroyFred(void *p)
|
|
{
|
|
free(p);
|
|
}</programlisting>
|
|
|
|
<para>When Cppcheck see this it understands that <function>CreateFred()
|
|
</function> will return allocated memory and that <function>DestroyFred()
|
|
</function> will deallocate memory.</para>
|
|
|
|
<para>Now, execute <command>cppcheck</command> this way:</para>
|
|
|
|
<programlisting>cppcheck --append=fred.cpp fred1.cpp</programlisting>
|
|
|
|
<para>The output from <command>cppcheck</command> is:</para>
|
|
|
|
<programlisting>Checking fred1.cpp...
|
|
[fred1.cpp:5]: (error) Memory leak: f</programlisting>
|
|
</section>
|
|
</chapter>
|
|
|
|
<chapter>
|
|
<title>Exception safety</title>
|
|
|
|
<para>Cppcheck has a few checks that ensure that you don't break the basic
|
|
guarantee of exception safety. It doesn't have any checks for the strong
|
|
guarantee yet.</para>
|
|
|
|
<para>Example:</para>
|
|
|
|
<programlisting>Fred::Fred() : a(new int[20]), b(new int[20])
|
|
{
|
|
}</programlisting>
|
|
|
|
<para>By default Cppcheck will not detect any problems in that
|
|
code.</para>
|
|
|
|
<para>To enable the exception safety checking you can use
|
|
<parameter class="command">--enable</parameter>:</para>
|
|
|
|
<programlisting>cppcheck --enable=exceptNew --enable=exceptRealloc fred.cpp</programlisting>
|
|
|
|
<para>The output will be:</para>
|
|
|
|
<programlisting>[fred.cpp:3]: (style) Upon exception there is memory leak: a</programlisting>
|
|
|
|
<para>If an exception occurs when <varname>b</varname> is allocated,
|
|
<varname>a</varname> will leak.</para>
|
|
|
|
<para>Here is another example:</para>
|
|
|
|
<programlisting>int *p;
|
|
|
|
int a(int sz)
|
|
{
|
|
delete [] p;
|
|
if (sz <= 0)
|
|
throw std::runtime_error("size <= 0");
|
|
p = new int[sz];
|
|
}</programlisting>
|
|
|
|
<para>Check that with Cppcheck:</para>
|
|
|
|
<programlisting>cppcheck --enable=exceptNew --enable=exceptRealloc except2.cpp</programlisting>
|
|
|
|
<para>The output from Cppcheck is:</para>
|
|
|
|
<programlisting>[except2.cpp:7]: (error) Throwing exception in invalid state, p points at deallocated memory</programlisting>
|
|
</chapter>
|
|
|
|
<chapter>
|
|
<title>HTML report</title>
|
|
|
|
<para>You can convert the XML output from cppcheck into a HTML report.
|
|
You'll need Python and the pygments module
|
|
(<ulink url="http://pygments.org/">http://pygments.org/</ulink>) for this to
|
|
work. In the Cppcheck source tree there is a folder
|
|
<filename class="directory">htmlreport</filename> that contains a script
|
|
that transforms a Cppcheck XML file into HTML output.</para>
|
|
|
|
<para>This command generates the help screen:</para>
|
|
|
|
<programlisting>htmlreport/cppcheck-htmlreport -h</programlisting>
|
|
|
|
<para>The output screen says:</para>
|
|
|
|
<programlisting>Usage: cppcheck-htmlreport [options]
|
|
|
|
Options:
|
|
-h, --help show this help message and exit
|
|
--file=FILE The cppcheck xml output file to read defects from.
|
|
Default is reading from stdin.
|
|
--report-dir=REPORT_DIR
|
|
The directory where the html report content is written.
|
|
--source-dir=SOURCE_DIR
|
|
Base directory where source code files can be found.</programlisting>
|
|
|
|
<para>An example usage:</para>
|
|
|
|
<programlisting>./cppcheck gui/test.cpp --xml 2> err.xml
|
|
htmlreport/cppcheck-htmlreport --file=err.xml --report-dir=test1 --source-dir=.</programlisting>
|
|
</chapter>
|
|
|
|
<chapter>
|
|
<title>Graphical user interface</title>
|
|
|
|
<section>
|
|
<title>Introduction</title>
|
|
|
|
<para>A Cppcheck GUI is available.</para>
|
|
|
|
<para>The main screen is shown immediately when the GUI is
|
|
started.</para>
|
|
</section>
|
|
|
|
<section>
|
|
<title>Check source code</title>
|
|
|
|
<para>Use the <guimenu>Check</guimenu> menu.</para>
|
|
</section>
|
|
|
|
<section>
|
|
<title>Inspecting results</title>
|
|
|
|
<para>The results are shown in a list.</para>
|
|
|
|
<para>You can show/hide certain types of messages through the
|
|
<guimenu>View</guimenu> menu.</para>
|
|
|
|
<para>Results can be saved to an XML file that can later be opened. See
|
|
<literal>Save results to file</literal> and <literal>Open
|
|
XML</literal>.</para>
|
|
</section>
|
|
|
|
<section>
|
|
<title>Settings</title>
|
|
|
|
<para>The language can be changed at any time by using the
|
|
<guimenu>Language</guimenu> menu.</para>
|
|
|
|
<para>More settings are available in
|
|
<menuchoice><guimenu>Edit</guimenu><guimenuitem>Preferences</guimenuitem>
|
|
</menuchoice>.</para>
|
|
</section>
|
|
|
|
<section>
|
|
<title>Project files</title>
|
|
|
|
<para>The project files are used to store project specific settings.
|
|
These settings are:</para>
|
|
|
|
<itemizedlist>
|
|
<listitem>
|
|
<para>include folders</para>
|
|
</listitem>
|
|
|
|
<listitem>
|
|
<para>preprocessor defines</para>
|
|
</listitem>
|
|
</itemizedlist>
|
|
|
|
<para>It isn't recommended to provide the paths to the standard C/C++
|
|
headers - Cppcheck has internal knowledge about ANSI C/C++ and it isn't
|
|
recommended that this known functionality is redefined. But feel free to
|
|
try it.</para>
|
|
|
|
<para>As you can read in <link linkend="preprocessor-configurations">chapter
|
|
3</link> in this manual the default is that Cppcheck checks all configurations.
|
|
So only provide preprocessor defines if you want to limit the checking.</para>
|
|
</section>
|
|
</chapter>
|
|
</book>
|
|
|