Sums and averages are self explanatory but more complex measurements are detailed here.
This measurement can be seen as an enhanced version of the traditionnal count of the number of lines of code : the longer the code, the higher the count will be.
Roughly spoken, it is approximately equivalent to counting ';' and '{' characters in source files.
Actually, the counter gets incremented by one for each of the following constructs:
Type | Examples | Comment |
Namespace definition | namespace my_namespace { namespace { namespace n = my_namespace::sub; | |
Type declaration | class MyClass; friend class MyClass; struct MyStruct; union MyUnion; enum MyEnum; typedef int ID; | class, struct, union, enum, typedef |
Type definition | class MyClass { class MyClass : public BaseClass { class { union MyUnion { union { struct MyStruct { struct { enum { enum MyEnum { | class, struct, union, enum |
Using declaration | using namespace std; using std::vector; | |
Variable declaration | int a; int a, b, c = 5, d = 6; char tab[12]; | No matter how many variables get actually declared through a comma separated list, only one statement is counted |
Function declaration | void method(); virtual void method() = 0; explicit MyClass( int i ); virtual ~MyClass(); | function, method, constructor, destructor |
Function definition | void method() { void method() throw() { MyClass() { ~MyClass() { MyClass::MyClass() { MyClass::~MyClass() { | function, method, constructor, destructor |
Base class initialization | : Base_ABC( data ) , Base( data ) | |
Field initialization | : field_( 0 ) , data_( data ) | |
Statement | i = 0; if( ok ) if( exit ) { if( 3 == 4 ); if( something() ) { ; } } else { | expression, if, else, while, do, for, switch, break, continue, return, throw, catch, goto |
Label | label : case 0 : default : | In a switch statement or to be referenced by a goto statement |
Not counted are empty statements, empty blocks, semicolons after closing brackets or single semicolons.
Of course, comments don't get counted.
Closing brackets also never get counted, the same applies to blocks in general.
This measurement provides an overview of the number of control flows of a given piece of code : the larger the code, the higher the count will be.
Whenever the control flow of a method splits, the counter gets incremented by one : basically it falls down to counting the if, for, while, etc.. statements in a method.
Each method has a minimum value of 1 by default. For each of the following constructs this value gets incremented by one :
Type | Examples | Comment |
If statement | if( ok ) if( exit ) { if( 3 == 4 ); if( something() ) { ; } i ? j | switch, else and : don't increment the counter |
Iteration statement | for( int i = 0; i < n; ++i ) { while( ok ) { do { | |
Case label | case 0: | default doesn't increment the counter |
Catch block | catch { | |
Logical Expression | i && j i || j |
Note that a simple method with a switch statement and a huge block of case statements can have a surprisingly high CCN value (still it has the same value when converting the switch block to an equivalent sequence of if statements).
CCN is also known as McCabe Metric.