Written and maintained by CASRAI Editorial Board
Last updated
Who this is for: researchers who write analysis scripts or scientific software and want to check source code for defects without running it. After reading you can run two free analyzers, Pylint (Python) and Cppcheck (C and C++), read their output, and judge what a clean result does and does not tell you.
Short answer: static analysis of source code means examining code without executing it. OWASP describes static code analysis tools as ones that “attempt to highlight possible vulnerabilities within ‘static’ (non-running) source code” (OWASP Static Code Analysis control, read 2026-11-08). This page covers code analysis; it is not about structural-engineering static analysis such as the load analysis done in SAP2000.
What it is used for in research
Research code is usually written by its users and rarely reviewed line by line. Running an analyzer is a cheap first check that can be repeated on every change. OWASP lists its strengths as scale (the tools can run over a whole code base, for example in nightly builds) and reliability on well-defined flaw types such as buffer overflows and SQL injection. Analyzers run during code review or implementation, before the code is deployed or used to produce results.
It complements, and does not replace, testing and review. For the wider practices around research software, see what software engineering is, the Better Scientific Software community guide and writing a software management plan. For a catalogue of the weakness classes that security-oriented analyzers report against, see CWE, and for security practices in health software lifecycles see IEC 81001-5-1.
What it cannot tell you
OWASP is explicit about the limits. A clean report is not evidence that code is correct or secure.
| Limit (as stated by OWASP) | What it means for research code |
|---|---|
| Finds a relatively small percentage of application security flaws | Passing the analyzer does not replace tests or review. |
| Authentication, access control and cryptography misuse are hard to detect | Do not rely on it for these areas. |
| False positives and false negatives occur | Treat each message as a prompt to look, not a verdict; some real problems are not reported. |
| Configuration issues are not visible in the code | Settings held outside the source are not checked. |
| A finding can be hard to verify | Expect to read the surrounding code to decide whether a message is real. |
| Code that cannot be compiled (missing libraries or build instructions) is hard to analyze | Keep dependencies and build steps documented so the analyzer can run. |
Install or access (official source only)
Pylint (Python)
The Pylint documentation (version 4.1.3, last updated 11 October 2026, read 2026-11-08) recommends pip:
pip install pylint
It also lists conda install pylint and sudo apt-get install pylint, noting that distribution packages can lag behind. Pylint supports Python interpreters that have not passed end of life; set py-version to the oldest version your project supports. Documentation: pylint.readthedocs.io.
Cppcheck (C and C++)
Cppcheck is documented in its manual at cppcheck.sourceforge.io/manual.html (read 2026-11-08). Obtain it from the project site.
Step-by-step task
Task A: check a Python module or package with Pylint
- Install Pylint as above.
- Run it on a module or package:
pylint mymodule.py. The general form ispylint [options] modules_or_packages. - To check a directory, run
pylint directory/mymodule.py; this works when the directory is a package, an implicit namespace package, or on the Python path. Before Pylint 2.15, usepylint --recursive=y mydir mymodule mypackage. Implicit namespace packages need--source-roots. Globbing such aspylint [options] packages/*/srcis supported. - Pylint does not import the module it checks, so check your
PYTHONPATHif it cannot resolve imports. - Narrow the checks with
--disable=<symbol>and--enable=<symbol>. To start from nothing, use--disable=allfollowed by--enable=.... Whole categories can be switched with letters, for example-d C,W. - Run
pylint --helporpylint --versionto see all options.
Task B: check C or C++ code with Cppcheck
- Run
cppcheck path; Cppcheck recurses through folders. - Restrict or exclude files with
--file-filter=<str>and-i <str>. - For a project with a compilation database, use
--project=compile_commands.json. - To silence a known false positive, use
--suppress=memleak:src/file1.cpp src/, a file with--suppressions-list=suppressions.txt, or an inline comment such as// cppcheck-suppress arrayIndexOutOfBoundstogether with--inline-suppr.
Output and how to read it
Pylint
By default Pylint prints text to standard output in the form {path}:{line}:{column}: {msg_id}: {msg} ({symbol}). The message ID is a letter plus four digits. The letter is the category: fatal, error, warning, refactor, convention or information. Use the symbol (the name in brackets) with --disable or --enable.
For other tools in a pipeline, --output-format= accepts text, parseable, colorized, json2, json, msvs, github and junit. Write to a file with --output=<file>, or send several formats at once: --output-format=json:somefile.json,colorized. Colour can be controlled with the NO_COLOR and FORCE_COLOR environment variables. A custom layout uses --msg-template with the fields path, line, column, module, obj, msg, msg_id, symbol and C.
Cppcheck
Each result carries a severity. The manual lists these severities.
| Severity | Meaning in the Cppcheck manual |
|---|---|
| error | Undefined behavior or another error, for example a leak |
| warning | Code that might show undefined behavior |
| style | Listed as a severity level; defined by name only in the sources read |
| performance | Listed as a severity level |
| portability | Listed as a severity level |
| information | Configuration problems |
Choose the output layout with --template=vs or --template=gcc, or write your own, for example --template="{file}:{line}:{column}: {severity}:{message}". Available specifiers include {file}, {line}, {column}, {callstack}, {inconclusive:text}, {severity}, {message}, {id}, {remark} and {code}. The manual’s examples use --enable=style and --enable=all to widen the checks.
Troubleshooting
- Pylint cannot find a module. Pylint does not import the module, so check
PYTHONPATH, run it on a package directory, or use--source-rootsfor implicit namespace packages. - Too many messages. Start with
--disable=alland enable the checks you want, or disable categories with-d. - A message looks wrong. False positives are expected (see the limits table). Suppress it narrowly, with a Cppcheck inline suppression or a Pylint disable for that symbol, rather than switching a check off everywhere.
- Cppcheck seems to miss files. Check
--file-filterand-i, or point it atcompile_commands.jsonwith--project. - Analysis is poor on code that does not build. OWASP notes that code which cannot be compiled, because libraries or build instructions are missing, is hard to analyze.
Free alternatives
| Tool | Languages (as documented) | Documentation |
|---|---|---|
| Pylint | Python | pylint.readthedocs.io |
| Cppcheck | C and C++ | Cppcheck manual |
OWASP maintains a list of source code analysis tools, and NIST publishes a list of source code security analyzers; both are linked from the OWASP Static Code Analysis control.
FAQ
What is static analysis of source code?
Examining code without running it, to highlight possible defects or vulnerabilities in the non-running source (OWASP, read 2026-11-08).
Does a clean report mean my code is correct?
No. OWASP states that these tools find a relatively small percentage of application security flaws and produce both false positives and false negatives.
Can I use the output in automated pipelines?
Pylint can emit json2, json, junit and github formats, and Cppcheck accepts custom templates, per their documentation.
Which Python and C/C++ tools are covered here?
Pylint and Cppcheck, both documented above with the dates read.
Sources
- OWASP, Static Code Analysis control (read 2026-11-08)
- Pylint documentation, version 4.1.3 (read 2026-11-08)
- Cppcheck manual (read 2026-11-08)







