Skip to content

Commit 9d235e9

Browse files
committed
doc
1 parent f5c4f4e commit 9d235e9

2 files changed

Lines changed: 116 additions & 1 deletion

File tree

man/manual-premium.md

Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -776,6 +776,120 @@ You can write comments about a suppression as follows:
776776
// cppcheck-suppress warningid ; some comment
777777
// cppcheck-suppress warningid // some comment
778778

779+
# Generating and using a baseline
780+
781+
When you first run Cppcheck on an existing codebase it's common to get a
782+
large number of warnings. A "baseline" lets you suppress all of today's
783+
warnings and see only *new* warnings introduced from now on.
784+
785+
This works by asking Cppcheck to include a content-based `hash` for every warning
786+
(computed from the surrounding code, not the line number), then converting today's
787+
warnings into an XML suppressions file keyed on `id` + `fileName` + `hash`. Because
788+
the hash is based on content rather than line number, warnings stay suppressed even
789+
after unrelated lines above them are added or removed. A warning only reappears if
790+
the code it actually points at changes, or a new warning shows up elsewhere.
791+
792+
## 1. Generate the baseline
793+
794+
Run Cppcheck with `--xml` and capture stderr (where Cppcheck writes its XML) to a
795+
file:
796+
797+
```sh
798+
cppcheck --enable=style --xml src 2> baseline-results.xml
799+
```
800+
801+
Use whatever combination of `--enable`/defines/include paths you normally
802+
analyze the project with — the suppressions you get out only cover the
803+
checks you ran.
804+
805+
## 2. Convert the results into a suppressions file
806+
807+
A [script](https://github.com/cppcheck-opensource/cppcheck/blob/main/tools/generate-baseline-suppressions.py) can be used to generate the baseline:
808+
```sh
809+
python3 generate-baseline-suppressions.py baseline-results.xml suppressions.xml
810+
```
811+
812+
This produces a `suppressions.xml` like:
813+
814+
```xml
815+
<?xml version="1.0"?>
816+
<suppressions>
817+
<suppress>
818+
<id>uninitvar</id>
819+
<fileName>src/file1.c</fileName>
820+
<hash>12345678</hash>
821+
</suppress>
822+
</suppressions>
823+
```
824+
825+
`suppressions.xml` needs to be shared by everyone who runs Cppcheck on this
826+
codebase, including CI.
827+
828+
Having a script instead of using some special cppcheck flags has the advantages:
829+
* it's flexible. You can tweak it if needed.
830+
* there is fewer flags for us to maintain and document, and for you to learn.
831+
832+
## 3. Use the baseline on future runs
833+
834+
```sh
835+
cppcheck --enable=style --xml --suppress-xml=suppressions.xml src
836+
```
837+
838+
Only warnings that aren't in the baseline are reported: new warnings in changed
839+
code, and warnings for checks/files that weren't covered when the baseline was
840+
generated.
841+
842+
## 4. Refreshing the baseline
843+
844+
Re-run steps 1-2 whenever you want to accept the current state as the new
845+
baseline (e.g. after cleaning up a batch of warnings, or deliberately accepting a
846+
new one). Regenerating overwrites `suppressions.xml` with an entry for every
847+
warning present at that time.
848+
849+
## The baseline doesn't need to be kept in sync
850+
851+
Once code that a baselined warning pointed at is fixed, refactored away, or
852+
deleted, its `suppress` entry in `suppressions.xml` becomes dead: nothing will
853+
ever match it again. You don't need to go find and remove it.
854+
855+
Cppcheck's `unmatchedSuppression` check (part of `--enable=all`) normally warns
856+
about suppressions that never matched anything, on the theory that a
857+
suppression nobody needs is probably a mistake. But it does *not* fire for
858+
`suppress` entries that carry a `<hash>` — which is every entry the baseline
859+
script generates. So a baseline file with plenty of dead entries produces no
860+
noise, and developers never need to prune it by hand — it only needs to be
861+
regenerated (step 4) when you deliberately want to reset what's accepted.
862+
863+
## Caveats
864+
865+
- A warning can only be suppressed this way if it carries a `hash` attribute in
866+
the XML output. Almost all checks compute one. Critical errors, i.e. syntax
867+
errors do not get hash and must be fixed. Certain information messages do not
868+
get hash neither.
869+
- Changed Cppcheck options might produce new warnings that are not suppressed
870+
by the baseline.
871+
- Cppcheck upgrades don't affect the hash directly (it isn't version-tagged),
872+
but if a new release for instance changes a check's message wording, the hash
873+
changes with it — so upgrading Cppcheck can resurrect baselined warnings for
874+
checks whose messages were reworded, even though nothing in the analyzed code
875+
changed.
876+
877+
## Strategies for gradually shrinking the baseline
878+
879+
A baseline makes it possible to adopt Cppcheck in CI immediately without
880+
fixing everything first, but nothing about it enforces that the accepted set
881+
of warnings actually shrinks over time.
882+
883+
Generic advice:
884+
885+
- **Prioritize by severity** Checks like `uninitvar` or
886+
`nullPointer` are more valuable to clear than `style` warnings; a baseline
887+
makes it possible to drive the highest-severity checks to zero first while
888+
deliberately leaving lower-risk ones suppressed longer.
889+
- **Be careful** Every fix is a code change, and every code change carries some
890+
risk of introducing a new bug. It can make sense to leave some things suppressed
891+
to minimize the risk that bugs are introduced in working code.
892+
779893
# XML output
780894

781895
Cppcheck can generate output in XML format. Use `--xml` to enable this format.

releasenotes.txt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,8 @@ Changed interface:
2020
-
2121

2222
Infrastructure & dependencies:
23-
- compile_commands.json - flexible handling of -isystem, --sysroot and -I flags through the script tweak-compile_commands.py.
23+
- flexible handling of -isystem, --sysroot and -I flags in compile_commands.json through the script tweak-compile_commands.py.
24+
- baseline functionality.
2425

2526
Other:
2627
- Added configuration file for Microsoft.GSL (Guideline Support Library).

0 commit comments

Comments
 (0)