This article describes my experience with the program C-Cover (v. 5.2.9b) by Bullseye Testing Technology. This is a code coverage analyzer that gathers and displays run time coverage statistics of C and C++ source code. Its capabilities include instrumenting the source code, accumulating the code's run time data, and displaying the data in its browser. While it supports networks and non-networked multiple workstations, my own experience has been on a single (Windows) workstation.
During compilation, C-Cover modifies a copy of the source code, inserting its probes, before passing it on to the compiler. The copy is then deleted. During run time, it detects and stores into its coverage database file the following information:
- whether each function was executed
- whether each if, if-else, while, for , and do-while control statement was executed
- the Boolean values of the expression within each control statement (decisions)
- the Boolean values of any logical sub-expressions—separated by logical-and (&&) and logical-or (||) —in each control statement (conditions)
- whether each switch's case and default labels are selected
- whether each C++ catch clause is entered
Coverage can be enabled or disabled via menu selections in Microsoft Visual Studio, with which C-Cover integrates. Enabling coverage means that during any subsequent compilation, C-Cover will insert its probes and when linking, link with the C-Cover library. The current coverage-enabled status is displayed in the status bar of the coverage browser. If coverage is enabled, at the start of a build a string is sent to the output window to that effect. The coverage-enabled status is not specific to any project or file and affects all subsequent builds.
The run time statistics of all covered projects are gathered into a single coverage file, whose path is set via an environment variable. (The file must exist prior to collection of the run time data; it is created during compilation.) The files whose data it displays are those which were compiled since its creation. So if the coverage file is deleted any time after a build, any files to be analyzed will need to be recompiled.
The coverage browser displays the coverage statistics and is separated into two panes, left and right (see Figures 1 and 2). The left pane displays a tree hierarchy of regions that the user can select. The right pane displays the statistics for the selected region. The regions in the left pane can be displayed as file or class-based. They are:
(for a file-based view)
- the coverage database file
- the names of the directories containing source files
- the names of the source files in the directory
- the names of the functions in the source file
(for a class-based view)
- the coverage database file
- the names of classes
- the names of the functions in the class
When the user selects any region above function name, the right pane displays the coverage statistics for that region, broken down according to the hierarchy’s next level of detail. When the user selects the name of a function, the right pane displays the annotated source code of the function, which shows the run time data gathered on the events listed.
When the browser displays statistics, the right pane is organized as five columns:
- names of the objects (directories, source files, functions or classes) within the selected region
- percent of functions covered in each object
- number of uncovered functions in each object
- percent of conditions/decisions covered in each object
- number of uncovered conditions/decisions in each object
A function is said to be covered if it is executed. A condition/decision is covered if its expressions have been executed with all possible Boolean outcomes. Each statistic is displayed