Details of the Collected Metrics

The following sections provide details for the collected function and file metrics. Although the metrics collected by CScout are considerably more accurate than those collected by programs that either do not parse the source code or parse the preprocessed code, they still employ approximations.

Where appropriate file and function metrics are collected both before and after preprocessing. In the database tables they appear as two records for each entity that are distinguished by the value of the precpp column.

Metrics Common to Files and Functions

Number of characters
See note 1.
Number of comment characters
See note 1.
Number of space characters
See note 1.
Number of line comments
See note 1.
Number of block comments
See note 1.
Number of lines
See note 1.
Maximum number of characters in a line
See note 1.
Maximum number of tokens in a statement
See note 1.
Maximum level of statement nesting
In order to avoid excessively inflating this metric when measuring sequences of the form

if (a) {
	...
} else if (b) {
	...
} else if (c) {
	...
} else
	...
}
this metric does not take into account the nesting of else clauses. Thus the above code will be given a nesting level of 1, rather than 3, which is implied by the following (actual) reading of the code.

if (a) {
	...
} else
	if (b) {
		...
	} else
		if (c) {
			...
		} else
			...
		}
See note 1. See note 4.
Maximum level of brace nesting
See note 1.
Maximum level of bracket nesting
See note 1.
Dangling brace nesting
See note 1.
Dangling bracket nesting
See note 1.
Number of unprocessed lines
See note 1.
Number of C preprocessor directives
See note 1.
Number of processed C preprocessor conditionals (ifdef, if, elif)
See note 1.
Number of defined C preprocessor function-like macros
See note 1.
Number of defined C preprocessor object-like macros
See note 1.
Number of tokens
Although during preprocessing whitespace is considered a valid token, this metric does not take whitespace tokens into account. This makes it easy to compare the number of tokens before preprocessing with the number of tokens after preprocessing. The two metrics are equal if no macro expansion takes place.
Number of statements or declarations
Nested statements are counted recursively. Thus

while (a)
	if (b)
		c();
counts as three statements.
Number of operators
See note 2.
Number of unique operators
See note 2.
Number of numeric constants
See note 1.
Number of character literals
See note 1.
Number of character strings
See note 1.
Number of token concatenation operators (##)
See note 1.
Number of token stringification operators (#)
See note 1.
Number of if statements
See note 3.
Number of else clauses
See note 3.
Number of switch statements
See note 3.
Number of case labels
See note 3.
Number of default labels
See note 3.
Number of break statements
See note 3.
Number of for statements
See note 3.
Number of while statements
This metric does not include the do .. while form. See note 3.
Number of do statements
See note 3.
Number of continue statements
See note 3.
Number of goto statements
See note 3.
Number of return statements
See note 3.
Number of assembly statements
See note 1.
Number of typeof operators
See note 1.
Number of project-scope identifiers
See note 1.
Number of file-scope (static) identifiers
See note 1.
Number of macro identifiers
See note 1.
Total number of object and object-like identifiers
Also includes macros.
Number of unique project-scope identifiers
See note 1.
Number of unique file-scope (static) identifiers
See note 1.
Number of unique macro identifiers
See note 1.
Number of unique object and object-like identifiers
Also includes macros.
Number of goto labels
See note 1.
Tokens added by macro expansion
See note 1.

File-Specific Metrics

Number of copies of the file
See note 1.
Number of defined project-scope functions
See note 1.
Number of defined file-scope (static) functions
See note 1.
Number of defined project-scope variables
See note 1.
Number of defined file-scope (static) variables
See note 1.
Number of complete aggregate (struct/union) declarations
Also includes complete declarations without a tag. See note 1.
Number of declared aggregate (struct/union) members
See note 1.
Number of complete enumeration declarations
See note 1.
Number of declared enumeration elements
See note 1.
Number of directly included files
This counts the number of header files that were directly included while processing the project's source files. If each file is processed exactly once, the metric is roughly similar to the number of #include directives in the project's files. See also note 1.

Function-Specific Metrics

Number of global namespace occupants at function's top
This metric measures the namespace pollution in the object namespace at the point before entering a function. Its value is the count of all macros as well as objects with file and project-scope visibility that are declared at the point it is measured. See note 1. See note 4.
Number of parameters (for macros)
See note 1.
Number of parameters (for functions)
See note 1.
Number of passed non-expression macro parameters
See note 1.
Fan-in (number of calling functions)
This is also listed under a function's details for functions that are not defined (and have not metrics associated with them).
Cyclomatic complexity (control statements)
This metric, CC1 measures the number of branch points in the function. In order to avoid misleadingly high values that occur from even trivial switch statements, this metric measures the complexity of a switch statement as 1.
Extended cyclomatic complexity (includes branching operators)
This metric, CC2, takes into account the nodes introduced by the Boolean-AND, boolean-OR, and conditional evaluation operators.
Maximum cyclomatic complexity (includes branching operators and all switch branches)
This metric, CC3, considers each case label as a separate node.
Structure complexity (Henry and Kafura)
This metric is calculcated as follows.
Cp = (fan_in * fan_out)2
Halstead volume
This metric is calculcated as follows.
HC = (number_of_operators + number_of_operands) * log2( unique_number_of_operators + unique_number_of_operands)
Where operands are object identifiers, macros, numeric and character constants. For the purpose of determining unique operands, each numeric or character constant is considered a separate operand.
Information flow metric (Henry and Selig)
This metric is calculcated as follows.
HCp = CC1 * Cp

Notes

Note 1
This metric is measured the first time a file is encountered in a project. The metric does not take into account regions that were not processed due to conditional compilation.
Note 2
When this metric is calculated before preprocessing, operators occuring in function-like macros are accounted to the corresponding macro. However, this makes it difficult to differentiate between commas used to separate function arguments and the comma operator. As a result the comma is ignored as an operator.
Note 3
When this metric is calculated before preprocessing, keywords occuring in function-like macros are accounted to the corresponding macro. As a result C keywords used during preprocessing as identifiers, as in

#define x(if, while, else) (if + while + else)
will be miscounted as keywords occuring in the corresponding macro. Furthermore keywords generated during preprocessing, as in

#define WHILE(x) while(x) {
#define WEND	 }

WHILE (x)
	foo();
WEND
will not be counted as occuring in the corresponding C function.
Note 4
This metric is not measured for function-like macros.