- METRIC.CBO - Coupling Between Objects
- METRIC.CC - McCabe Cyclomatic Complexity
- METRIC.CLLOCRIF - Comment/Logical Lines in Files
- METRIC.CLLOCRIM - Comment/Logical Lines in Methods
- METRIC.CLLOCRIT - Comment/Logical Lines in Types
- METRIC.DIF - Depth of Nested 'if' Statements
- METRIC.ECC - Essential Cyclomatic Complexity
- METRIC.FO - Fan Out
- METRIC.HDIFM - Halstead Difficulty
- METRIC.HEFM - Halstead Effort
- METRIC.HICM - Halstead Intelligent Content
- METRIC.HLENM - Halstead Program Length
- METRIC.HLEVM - Halstead Program Level
- METRIC.HNOBM - Halstead Number of Bugs
- METRIC.HTTPM - Halstead Time to Program
- METRIC.HVOCM - Halstead Program Vocabulary
- METRIC.HVOLM - Halstead Program Volume
- METRIC.IDOC - Inheritance Depth of Class
- METRIC.LCOM - Lack of Cohesion
- METRIC.MCC - Modified Cyclomatic Complexity
- METRIC.MI - Maintainability Index
- METRIC.NBD - Nested Blocks Depth
- METRIC.NOBLIF - Blank Lines in Files
- METRIC.NOBLIM - Blank Lines in Methods
- METRIC.NOBLIT - Blank Lines in Types
- METRIC.NOC - Number of Classes
- METRIC.NOCLIF - Comment Lines in Files
- METRIC.NOCLIM - Comment Lines in Methods
- METRIC.NOCLIT - Comment Lines in Types
- METRIC.NOF - Number of Files
- METRIC.NOLLOCIF - Logical Lines in Files
- METRIC.NOLLOCIM - Logical Lines in Methods
- METRIC.NOLLOCIT - Logical Lines in Types
- METRIC.NOMIT - Number of Methods in Types
- METRIC.NOPAR - Parameters of Methods
- METRIC.NOPLIF - Physical Lines in Files
- METRIC.NOPLIM - Physical Lines in Methods
- METRIC.NOPLIT - Physical Lines in Types
- METRIC.NOPRIVMIT - Private Members of Types
- METRIC.NOPROTMIT - Protected Members of Types
- METRIC.NOPUBMIT - Public Members of Types
- METRIC.NORET - Number of Returns in Methods
- METRIC.NOSLIF - Source Lines in Files
- METRIC.NOSLIM - Source Lines in Methods
- METRIC.NOSLIT - Source Lines in Types
- METRIC.NOT - Number of Types
- METRIC.RFC - Response for Class
- METRIC.SCC - Strict Cyclomatic Complexity
- METRIC.WMC - Weighted Methods of Class

This metric counts how many types are used by a given type. A type is used (coupled to) another type when: - its field (either instance or static) is accessed - its method (either instance or static) is called - its constructor is called (implicit constructor calls are only counted if it is explicitly declared in a class) The following instances are not counted: - use of base types

v10.1.3

A high number of coupled object classes means types depend on each other too much and will be hard to reuse. The more independent a type is, the easier it is to reuse in other applications. In order to improve modularity and promote reuse, coupling inter-object types should be kept to a minimum. The more couples, the higher the sensitivity to changes in other parts of the design, resulting in more difficult maintenance.

Metric Code 0 class Foo { public: void foo() {} int x; }; // class is not coupled to its parents 0 class DerivedFoo : public Foo { public: int dFoo() { foo(); return x; } }; 2 class Bar { public: int bar(Foo a) { DerivedFoo b; 1 a.foo(); // coupling to Foo a.x = 0; // coupling to Foo 1 return b.dFoo(); // coupling to DerivedFoo } };

[Top]

Introduced by Thomas McCabe, cyclomatic complexity measures the number of linearly independent paths through which messages can pass. The result of this measurement is a single ordinal number that can be used to compare the cyclomatic complexity across programs. A program module's complexity can also be interpreted as the cost of producing test cases for the code. Methods with low cyclomatic complexity imply that decisions are deferred through message passing--though this does not imply that a method is not complex or intricate. Methods with a high complexity tend to be more difficult to understand, maintain, and test; thus complex methods adversely affect an application's reliability. The metric is computed by counting the number of decisions in the flow graph and incrementing the number be one, as in the following formula: C = Number of decisions + 1 If C is greater than or equal to 10, industry standards recommend splitting the method since the more complex the program the harder it is to test and comprehend. For all variations of a CC metric, each occurrence of the following expressions count as a decision point: - if, for, while, do-while, case - conditional expression a?b:c inside if, for, while, do-while condition This metric measures the McCabe Cyclomatic Complexity. CC = Number of decisions + 1 See Cyclomatic Complexity, for details. In this metric, every condition and switch case increase the metric value. Boolean operators, e.g., && and ||, are not treated as decisions and do not increase the metric value

10.1.3

Metric Code +1 void foo() { int i, j, k; +1 if(i > 0) { //... +1 } if(i > 1) { // ... } else { //... } +1 for(i = 0; i < 10; i++) { //... } +1 while(i > 0) { //... } do { //.... } +1 while(i > 0); +1 if(i > 0 && j > 0) { //... } +1 if(i > 0 || j > 0) { //... } k = (i > 0) ? 1 : 0; switch(i) { case 0: +1 case 1: i++; +1 case 2: i--; default: i = 10; } } Total: 10

http://en.wikipedia.org/wiki/Cyclomatic_complexity

[Top]

Ratio of Comments to Number of Logical Lines metrics report the ratio of comment lines to logical lines of code. See "Number of Comment Lines" metrics for the definition of comments. See "Number of Logical Lines" metrics for the definition of logical lines. This metric measures the proportion of comment lines to logical lines of code in files.

10.1.3

Comments Logical Lines Code +1 /* comment */ int foo(int i) { +1 int j = 10; +1 i = i + j; +1 return i; } +1 /* +1 * comment +1 */ class Foo { public: +1 int foo1(int i); // comment +1 int foo2(int j); // comment void bar(int k) { +1 int l = 0; +1 l = l + k; +2 l = foo1(0); k = foo2(1); +1 if(l > 0) +1 l = foo1(foo2(2)) + k; else +1 l = 0; } }; Total: 6 Total: 10 Ratio: .6

[Top]

CRatio of Comments to Number of Logical Lines metrics report the ratio of comment lines to logical lines of code. See "Number of Comment Lines" metrics for the definition of comments. See "Number of Logical Lines" metrics for the definition of logical lines. This metric measures the proportion between comment lines and logical lines of code in methods.

10.1.3

Comments Logical Lines Code +1 /* comment */ int foo(int i) { +2 int j; int k; +1 i = (i + j) * k; +1 return i; } Total: 1 Total: 4 Ratio: .25

[Top]

Ratio of Comments to Number of Logical Lines metrics report the ratio of comment lines to logical lines of code. See "Number of Comment Lines" metrics for the definition of comments. See "Number of Logical Lines" metrics for the definition of logical lines. This metric measures the ratio of comment lines to logical lines of code in types.

10.1.3

Comments Logical Lines Code +1 / comment class Foo { +1 /* comment */ int foo1(int i) { +1 int j = 10; +1 i = i + j; +1 return i; } +1 /* comment */ int foo2(int k) { +1 int j = 20; +1 j = k + j; +1 return j; } }; Total: 3 Total: 6 Ratio: .5

[Top]

This metric calculates the maximum depth of if blocks in a method. It assumes that the depth of the initial block (the first set of curly brackets) is 0, and nested if blocks increase the value.

v10.3.0

A large number of nested if statements makes code difficult to understand and maintain.

void test2(int a) { for(;;){ if(true){//1 if(true){//2 switch(a){ case 1: while(true){ if(true){//3 if(true){//4 } } } case 2: if(true){//3 while(true){ if(true){//4 } else{ if(true){//5 } } } } } } } } } Max: 5

[Top]

Introduced by Thomas McCabe, cyclomatic complexity measures the number of linearly independent paths through which messages can pass. The result of this measurement is a single ordinal number that can be used to compare the cyclomatic complexity across programs. A program module's complexity can also be interpreted as the cost of producing test cases for the code. Methods with low cyclomatic complexity imply that decisions are deferred through message passing--though this does not imply that a method is not complex or intricate. Methods with a high complexity tend to be more difficult to understand, maintain, and test; thus complex methods adversely affect an application's reliability. The metric is computed by counting the number of decisions in the flow graph and incrementing the number be one, as in the following formula: C = Number of decisions + 1 If C is greater than or equal to 10, industry standards recommend splitting the method since the more complex the program the harder it is to test and comprehend. For all variations of CC metric each occurrence of the following expressions count as a decision point: - if, for, while, do-while, case (non-empty), catch - conditional expression a?b:c inside if, for, while, do-while condition This metric measures the Essential Complexity value for each method. The Essential Complexity metric quantifies the extent to which software is unstructured. The metric is calculated according to the formula: EC = Number of unstructured decisions + 1 Unstructured decisions refer to conditional jumps into or out of other decisions, for example: - goto inside if, which is inside switch - return inside while, which is inside for Decisions that contain unstructured decisions are also considered unstructured.

10.1.3

According to McCabe, "structured programming avoids unmaintainable 'spaghetti code' by restricting the usage of control structures to those that are easily analyzed and decomposed." You can compare Essential Complexity and Cyclomatic Complexity to find methods that are complicated but well structured, which means they can be refactored.

Metric Code +1 void foo(int x, int y) { do { +1 if(y) { break; } +1 } while(x); switch(y) { +1 case 1: +1 if (x) { return; } break; } +1 if (x) { +1 if (y) { goto AFTER; } } x++; AFTER: y++; } Total: 7

[Top]

This metric counts the number of reference types in methods. Reference types cover: - Method parameters - Constructor, method calls - Field access - Type operators (e.g., typeid) - Cast operators to given type - Catch exception clauses - sizeof on given type - pointers and references Use of base types is not counted.

v10.1.3

Metric Code 0 class Foo { public: void foo() {} int x; }; // Parent classes are not counted 0 class DerivedFoo : public Foo { public: int dFoo() { foo(); return x; } }; 2 class Bar { public: +1 int bar(Foo a) { // uses Foo +1 DerivedFoo* b; // uses DerivedFoo a.foo(); a.x = 0; return b->dFoo(); } };

[Top]

This metric is a Halstead complexity measure. It describes how difficult a method is to write according to the following: D = (n1/2) * (N2/n2) Where: n1 the number of distinct operators n2 the number of distinct operands N2 the total number of operands

v10.2.2

Operator Operand Code class SimpleClass { +1 +4 long Factorial(long n) { +3 +2 if (n < 0) { +3 +2 throw ::invalid_argument("Not defined for negative numbers"); } +3 +2 if (n == 0) { // By definition, 0! is 1 +1 +1 return 1; } +4 +4 return n * Factorial(n - 1); } }; Metric: 9.64 N1=15 (all), n1=9 (distinct) N2=15 (all), n2=7 (distinct) Operators: '(' (5x), 'if' (2x), '<', 'throw', '::', '==', 'return' (2x), '*', '-' Operands: 'long' (2x), 'Factorial' (2x), 'n' (5x), 'invalid_argument', "Factorial is not defined for negative numbers", '0' (2x), '1' (2x) Ignored: '{', '}', ')', ';'

[Top]

This metric is a Halstead complexity measure. It describes how much effort is required to generate a method. E = D * V Where: D the Halstead Difficulty "see Halstead Difficulty (METRIC.HDIFM)". V the Halstead Volume "see Halstead Program Volume (METRIC.HVOLM)". Both above values are fully described in two separates rules Difficulty and Volume.

v10.2.2

Operator Operand Code class SimpleClass { +1 +4 long Factorial(long n) { +3 +2 if (n < 0) { +3 +2 throw ::invalid_argument("Not defined for negative numbers"); } +3 +2 if (n == 0) { // By definition, 0! is 1 +1 +1 return 1; } +4 +4 return n * Factorial(n - 1); } }; Metric: 1157.14 N1=15 (all), n1=9 (distinct) N2=15 (all), n2=7 (distinct) Operators: '(' (5x), 'if' (2x), '<', 'throw', '::', '==', 'return' (2x), '*', '-' Operands: 'long' (2x), 'Factorial' (2x), 'n' (5x), 'invalid_argument', "Factorial is not defined for negative numbers", '0' (2x), '1' (2x) Ignored: '{', '}', ')', ';'

[Top]

This metric a Halstead complexity measure. It is a measure of the amount of information in the shortest version of a program. Intelligent content is described by following formula: I = L * V Where: V is the Halstead Volume "see Halstead Program Volume (METRIC.HVOLM)". L is the Program Level "see Halstead Program Level (METRIC.HLEV)".

v10.2.2

Operator Operand Code class SimpleClass { +1 +4 long Factorial(long n) { +3 +2 if (n < 0) { +3 +2 throw ::invalid_argument("Not defined for negative numbers"); } +3 +2 if (n == 0) { // By definition, 0! is 1 +1 +1 return 1; } +4 +4 return n * Factorial(n - 1); } }; Metric: 12.44 N1=15 (all), n1=9 (distinct) N2=15 (all), n2=7 (distinct) Operators: '(' (5x), 'if' (2x), '<', 'throw', '::', '==', 'return' (2x), '*', '-' Operands: 'long' (2x), 'Factorial' (2x), 'n' (5x), 'invalid_argument', "Factorial is not defined for negative numbers", '0' (2x), '1' (2x) Ignored: '{', '}', ')', ';'

[Top]

This metric is a Halstead complexity measure. It describes the size of a method according to the following formula: N = N1 + N2 Where: N1 the total number of operators N2 the total number of operands

v10.2.2

Operator Operand Code class SimpleClass { +1 +4 long Factorial(long n) { +3 +2 if (n < 0) { +3 +2 throw ::invalid_argument("Not defined for negative numbers"); } +3 +2 if (n == 0) { // By definition, 0! is 1 +1 +1 return 1; } +4 +4 return n * Factorial(n - 1); } }; Metric: 30 N1=15 (all), n1=9 (distinct) N2=15 (all), n2=7 (distinct) Operators: '(' (5x), 'if' (2x), '<', 'throw', '::', '==', 'return' (2x), '*', '-' Operands: 'long' (2x), 'Factorial' (2x), 'n' (5x), 'invalid_argument', "Factorial is not defined for negative numbers", '0' (2x), '1' (2x) Ignored: '{', '}', ')', ';'

[Top]

This metric is a Halstead complexity measure. It can be used to create other multi-metrics. Describes the inverse of the difficulty metric according to the following formula: L = 1 / D Where: D the Halstead Difficulty "see Halstead Difficulty (METRIC.HDIFM)".

v10.2.2

Operator Operand Code class SimpleClass { +1 +4 long Factorial(long n) { +3 +2 if (n < 0) { +3 +2 throw ::invalid_argument("Not defined for negative numbers"); } +3 +2 if (n == 0) { // By definition, 0! is 1 +1 +1 return 1; } +4 +4 return n * Factorial(n - 1); } }; Metric: 0.1 N1=15 (all), n1=9 (distinct) N2=15 (all), n2=7 (distinct) Operators: '(' (5x), 'if' (2x), '<', 'throw', '::', '==', 'return' (2x), '*', '-' Operands: 'long' (2x), 'Factorial' (2x), 'n' (5x), 'invalid_argument', "Factorial is not defined for negative numbers", '0' (2x), '1' (2x) Ignored: '{', '}', ')', ';'

[Top]

This metric is a Halstead complexity measure. The original purpose of this metrics is to define how many bugs can be delivered, but it should be used especially for defect prediction. This rule may help optimize the work of testers and programmers to focus on problematic system parts rather than the evaluation of the quality of the code. The Number Of Bugs metric is described by the following formula: B = E^(2/3) / 3000 Where: E is the Halstead Effort that is fully described in a separate rule "see Halstead Effort (METRIC.HEFM)"

v10.2.2

Operator Operand Code class SimpleClass { +1 +4 long Factorial(long n) { +3 +2 if (n < 0) { +3 +2 throw ::invalid_argument("Not defined for negative numbers"); } +3 +2 if (n == 0) { // By definition, 0! is 1 +1 +1 return 1; } +4 +4 return n * Factorial(n - 1); } }; Metric: 0.037 N1=15 (all), n1=9 (distinct) N2=15 (all), n2=7 (distinct) Operators: '(' (5x), 'if' (2x), '<', 'throw', '::', '==', 'return' (2x), '*', '-' Operands: 'long' (2x), 'Factorial' (2x), 'n' (5x), 'invalid_argument', "Factorial is not defined for negative numbers", '0' (2x), '1' (2x) Ignored: '{', '}', ')', ';'

[Top]

This metric is a Halstead complexity measure. It describes how much time is needed to understand a program, sometimes defined as testing time, according to the following formula: T = E / S Where: E is the Halstead Effort "see Halstead Effort (METRIC.HEFM)". S is the Stroud number indicating the number of elementary decisions per second that a person may execute. It has an arbitrary default value of 18.

v10.2.2

Operator Operand Code class SimpleClass { +1 +4 long Factorial(long n) { +3 +2 if (n < 0) { +3 +2 throw ::invalid_argument("Not defined for negative numbers"); } +3 +2 if (n == 0) { // By definition, 0! is 1 +1 +1 return 1; } +4 +4 return n * Factorial(n - 1); } }; Metric: 64.29 N1=15 (all), n1=9 (distinct) N2=15 (all), n2=7 (distinct) Operators: '(' (5x), 'if' (2x), '<', 'throw', '::', '==', 'return' (2x), '*', '-' Operands: 'long' (2x), 'Factorial' (2x), 'n' (5x), 'invalid_argument', "Factorial is not defined for negative numbers", '0' (2x), '1' (2x) Ignored: '{', '}', ')', ';'

[Top]

This metric is a Halstead complexity measure. It describes how many elements are needed to implement a method. The Vocabulary metric is described by following formula: n = n1 + n2 Where: n1 the number of distinct operators n2 the number of distinct operands

v10.2.2

Operator Operand Code class SimpleClass { +1 +4 long Factorial(long n) { +3 +2 if (n < 0) { +3 +2 throw ::invalid_argument("Not defined for negative numbers"); } +3 +2 if (n == 0) { // By definition, 0! is 1 +1 +1 return 1; } +4 +4 return n * Factorial(n - 1); } }; Metric: 16 N1=15 (all), n1=9 (distinct) N2=15 (all), n2=7 (distinct) Operators: '(' (5x), 'if' (2x), '<', 'throw', '::', '==', 'return' (2x), '*', '-' Operands: 'long' (2x), 'Factorial' (2x), 'n' (5x), 'invalid_argument', "Factorial is not defined for negative numbers", '0' (2x), '1' (2x) Ignored: '{', '}', ')', ';'

[Top]

This metric is a Halstead complexity measure. It describes how much mental comparison is needed to write a method. The Volume metric is described by following formula: V = N * log2(n) Where: N is the program length "see Length (METRIC.HLENM)" n is the program vocabulary "see Vocabulary(METRIC.HVOCM)"

v10.2.2

Operator Operand Code class SimpleClass { +1 +4 long Factorial(long n) { +3 +2 if (n < 0) { +3 +2 throw ::invalid_argument("Not defined for negative numbers"); } +3 +2 if (n == 0) { // By definition, 0! is 1 +1 +1 return 1; } +4 +4 return n * Factorial(n - 1); } }; Metric: 120 N1=15 (all), n1=9 (distinct) N2=15 (all), n2=7 (distinct) Operators: '(' (5x), 'if' (2x), '<', 'throw', '::', '==', 'return' (2x), '*', '-' Operands: 'long' (2x), 'Factorial' (2x), 'n' (5x), 'invalid_argument', "Factorial is not defined for negative numbers", '0' (2x), '1' (2x) Ignored: '{', '}', ')', ';'

[Top]

This metric measures the ordinal distance from the class to the root of the inheritance tree according to the following rules: - Classes that have no base type in source code have an inheritance depth of class (IDOC) of 0 - All other classes have a depth of 1 plus the depth of their super class

v10.1.3

This metric primarily evaluates reuse, but it also relates to understandability and testability. The depth of a class within the inheritance hierarchy is the maximum length from the class node to the root of the tree and is measured by the number of ancestor classes. The deeper a class is in the hierarchy, the greater the number of methods and state variables it is likely to inherit, which makes predicting its behavior difficult. If the majority of IDOC values are below 2, it may mean that the code is not taking full advantage of Object Oriented design and inheritance. Conversely, industry standards recommend a maximum IDOC value of 5 because deeper trees constitute greater design complexity as more methods and classes are involved. Although it can be difficult to understand a system with many inheritance layers, there is greater potential for reusing tested inherited methods.

IDOC Code 0 class Foo {/**/}; 1 class Bar : public Foo {/**/}; 2 class Baz : private Bar {/**/}; 0 struct S11 {/**/}; 0 struct S12 {/**/}; 1 struct S2 : public S11 {/**/}; 2 struct S3 : public S12, public S2 {/**/};

[Top]

This metric calculates Lack of Cohesion in Methods (LCOM) as defined by Henderson-Sellers ("LCOM3" or the "LCOM*" variant). Only fields that are accessed by at least one method, and methods that access at least one field, are included in the count. Cohesion is a measure of relatedness in a class. A class with low cohesion means that it may perform various tasks that have little relation to each other. These classes may be candidates for refactoring into separate, more targeted, classes. LCOM is determined according to the following formula: LCOM = (avg(m(f)) - m)/(1-m) - m is the number of methods that use at least one field - m(f) is the number of methods that use field 'f' - avg(m(f)) is the average number of methods that use field f computed over all fields that are used by at least one method, thus: avg(m(f)) = (m(f1) + m(f2) + ... + m(fn)) / n LCOM can take values between 0 and 1, where 0 means class is cohesive (lack of cohesion is at minimum), and 1 means class is not cohesive (lack of cohesion is at maximum). A value of 0 means that the class is cohesive. Every field is used by every method; and all methods work on the same set of fields and perform common tasks. A value of 1 means that the class is not cohesive. Every field is used by only 1 method; and every method has its own field and performs its own task separate from other methods/tasks.

v10.1.3

Metric Code 0 class Foo { void foo1() { x = 0; y = 0; } void foo2() { x = y; } int x; int y; }; 1 class Bar { void foo1() { x = 0; } void foo2() { y = 0; } int x; int y; }; 0.5 class Baz { void foo1() { x = 0; } void foo2() { y = x; } int x; int y; };

[Top]

Introduced by Thomas McCabe, cyclomatic complexity measures the number of linearly independent paths through which messages can pass.The result of this measurement is a single ordinal number that can be used to compare the cyclomatic complexity across programs. A program module's complexity can also be interpreted as the cost of producing test cases for the code. Methods with low cyclomatic complexity imply that decisions are deferred through message passing--though this does not imply that a method is not complex or intricate. Methods with a high complexity tend to be more difficult to understand, maintain, and test; thus complex methods adversely affect an application's reliability. The metric is computed by counting the number of decisions in the flow graph and incrementing the number by one, as in the following formula: C = Number of decisions + 1 If C is greater than or equal to 10, industry standards recommend splitting the method since the more complex the program the harder it is to test and comprehend. For all variations of CC metric each occurrence of the following expressions count as a decision point: - if, for, while, do-while, case - conditional expression a?b:c inside if, for, while, do-while condition This metric measures the Modified Cyclomatic Complexity according to the following formula: MCC = Number of decisions + 1 Every condition increases the metric value. Switch statements with multiple branches are treated as a single decision.

10.1.3

Metric Code +1 void foo() { int i, j, k; +1 if(i > 0) { //... +1 } if(i > 1) { // ... } else { //... } +1 for(i = 0; i < 10; i++) { //... } +1 while(i > 0) { //... } do { //.... } +1 while(i > 0); +1 if(i > 0 && j > 0){ //... } +1 if(i > 0 || j > 0){ //... } k = (i > 0) ? 1 : 0; +1 switch(i) { case 0: case 1: i++; case 2: i--; default: i = 10; } } Total: 9

[Top]

Maintainability Index is a composite metric that incorporates a number of traditional source code metrics into a single number that indicates relative maintainability. Maintainability indices of 65 and above indicate acceptable maintainability (above 85 indicates good maintainability). Maintainability indices below 65 indicate that the software will be difficult to maintain. Formula The maintainability index of a type is: MI = 171 - 5.2*ln(avgHV) - 0.23*avgSCC - 16.2*ln(avgLOC) + 50*sin(sqrt(2.46*CMR)) Where: - avgHV is the average Halstead Volume of methods of the type. The Halstead Volume is a measurement of implementation size and complexity. It is calculated as V = N * log2(n), where N is the program length and n is the program vocabulary. Program length is the total number of operators and (atomic) operands, while program vocabulary is the number of distinct operators and operands. - avgSCC is the average Strict Cyclomatic Complexity of methods of the type. See Strict Cyclomatic Complexity (METRIC.SCC). - avgLOC is the average number of lines of code of methods of the type. This is equal to the Physical Lines of Code of Method and Blank Lines of Code of Method metrics. See Number of Physical Lines in Method (METRIC.NOPLIM), and Number of Blank Lines in Method (METRIC.NOBLIM)). - CMR is the Ratio of Lines of Comments in Methods (METRIC.NOCLIM) to Lines of Code in Methods of the type, where Lines of Code in Method are all non-blank lines in method.

v10.1.3

Metric Code // comment Bar class Bar { 144.95 public: // comment bar int bar(int i, int j) { if(i > 0 && j > 0) { return 1; } return 0; } }; 108.7 class Foo { public: int foo(int i, int j) { if(i > 0) { if(j > 0) { return 1; } else { return 0; } } else { return 0; } } };

[Top]

This metric calculates the maximal nested blocks depth for a method. The initial block (i.e., the first set of curly braces) has a depth of 0. Each additional set of curly braces counts as an additional block.

v10.1.3

Having too many nested blocks makes the code hard to understand and maintain. When the METRIC.NBD value is too high, the code should be reviewed and refactored if necessary.

Depth Code int foo(int b, int i) 0 { if (b > 0) 1 { int j; for (j = 0; j < i; j++) 2 { if (i > 10) 3 { if (j == b) return 0; else return 1; } } if (b > 10) 2 { return 2; } } return 0; } Max: 3

[Top]

Number of Blank Lines metrics count how many lines do not have code or comments. A blank line is an empty line or line that has only whitespaces. This metric counts the number of blank lines in files.

10.1.3

Metric Code /* Copyright */ +1 // empty line below and above +1 void foo() { +1 // only spaces in line above +1 // only tabs in line above +1 // only tabs and spaces in line above } Total: 5

[Top]

Number of Blank Lines metrics count how many lines do not have code or comments. A blank line is an empty line or line that has only whitespaces. This metric counts number of blank lines that belong to methods. It includes comments that precede the methods. See METRIC.NOPLIM for details on how lines of Anonymous Methods are measured.

10.1.3

Metric Code class Foo { // comment // comment Bar void Bar() +1 { +1 } }; Total: 2

[Top]

Number of Blank Lines metrics count how many lines do not have code or comments. A blank line is an empty line or line that has only whitespaces. This metric counts number of blank lines that belong to types. It includes comments that precedes the types.

10.1.3

Metric Code // comment // comment Foo class Foo { void Bar() { +1 } +1 }; Total: 2

[Top]

This metric counts the number of classes per class. Anonymous classes and enumerations are not counted as classes.

v10.2.2

Metric Code +1 class Foo { }; +1 class Bar { }; union Baz { }; enum En { }; Total: 2

[Top]

The Number of Comment Lines metrics measure how many lines have at least one comment, have the beginning or ending of a comment, or are inside a comment. The three metrics allow you to measure how well the analyzed code is commented. This metric measures the number of comment lines in files.

10.1.3

Metric Code +1 // comment struct Foo { }; +1 /* comment +1 * +1 */ void foo() { +1 int i; /* comment */ } Total: 5

[Top]

The Number of Comment Lines metrics measure how many lines have at least one comment, have the beginning or ending of a comment, or are inside a comment. The three metrics allow you to measure how well the analyzed code is commented. This metric counts the number of comment lines that belong to methods, including comments that precede the method definition.

10.1.3

Metric Code // comment class Foo { +1 // comment Bar void Bar() { +1 // empty } }; Total: 2

[Top]

The Number of Comment Lines metrics measure how many lines have at least one comment, have the beginning or ending of a comment, or are inside a comment. The three metrics allow you to measure how well the analyzed code is commented. This metric counts the number of comment lines per type, including comments that precede the type definition.

10.1.3

Metric Code // comment +1 // comment Foo class Foo { +1 // comment Bar void Bar() { +1 // empty } }; Total: 3

[Top]

This metric counts the number of source files. Depending on the DTP Engine, specific files by their extensions are included.

10.1.3

[Top]

Number of Logical Lines metrics measures the number of logical lines of source code. Logical lines are sometimes called statements. One logical line may span over several physical lines of code or there may be many logical lines in one physical line of code. This metric measures the number of logical lines in file.

10.1.3

Metric Code // comment Foo class Foo { public: // comment foo +1 int foo(int j) { /* comment */ +1 int i; /* comment */ if ((i + j) > 0) { +1 return 1; +1 } +1 } +1 }; Total: 6

[Top]

Number of Logical Lines metrics measures the number of logical lines of source code. Logical lines are sometimes called statements. One logical line may span over several physical lines of code or there may be many logical lines in one physical line of code. This metric counts the number of logical lines that belong to methods.

10.1.3

Metric Code int foo1(int i); int foo2(int j); void bar(int k) { +1 int l = 0; +1 l = l + k; +2 l = foo1(0); k = foo2(1); +1 if(l > 0) +1 l = foo1( foo2(2) ); else +1 l = 0; } Total: 7

[Top]

Number of Logical Lines metrics measures the number of logical lines of source code. Logical lines are sometimes called statements. One logical line may span over several physical lines of code or there may be many logical lines in one physical line of code. This metric counts the number of logical lines that belong to types.

10.1.3

Metric Code class Foo { public: int foo(int i) { +1 i = i + 10; +1 return i; } int foo1(int i); int foo2(int j); void bar(int k) { +1 int l = 0; +1 l = l + k; +2 l = foo1(0); k = foo2(1); +1 if(l > 0) +1 l = foo1(foo2(2)) + k; else +1 l = 0; } }; Total: 9

[Top]

This metric counts the number of methods in types, including: - methods - constructors - destructors

v10.1.3

Metric Code class Foo { public: +1 Foo(); +1 ~Foo(); +1 void foo(){} }; Foo::~Foo() { } Total: 3

[Top]

This metric counts the number of parameters (arguments) of methods, constructors, destructors or finalizers.

v10.1.3

Methods with a large number of parameters are often harder to reuse because they tend to be specialized, which implies that classes are missing from the model. The industry standard default limits for the number of method parameters (NOPAR) are {0,4}. If the amount of parameters exceeds 4, you should consider moving an invoked method or pass an object. In general, methods and constructors with more than 3 parameters are harder to comprehend, use, and maintain. Source code containing invocations of methods that have long parameter lists tend to be error-prone. Invoking methods with similar signatures also tends to result in errors.

Metric Code 3 void foo(int x, int y, int z); 3 void foo(int x, int y, int z){ /* */ } class Foo { public: 4 void bar(short s, float f, double z, char c); 0 void baz(){ /* */ } }; void Foo::bar(short s, float f, double z, char c){ /* */ }

[Top]

Number of Physical Lines metrics measures the total number of lines. It covers all kinds of lines: source code lines, lines with comments, and blank lines. This metric measures the number of physical lines in file.

10.1.3

Metric Code +1 // comment +1 struct Foo +1 { +1 +1 }; +1 +1 void foo() { +1 /* comment */ +1 } Total: 9

[Top]

Number of Physical Lines metrics measures the total number of lines. It covers all kinds of lines: source code lines, lines with comments, and blank lines. This metric counts the number of physical lines that belong to methods. It includes comments that precede the methods. Anonymous methods belong to the closest regular (nested or not) methods. In the 'Anonymous methods' example part, method Bar has 9 lines and no other method is reported:

10.1.3

Metric Code // comment Foo class Foo { +1 // comment Bar +1 void Bar() +1 { +1 +1 } }; Total: 5 Anonymous Methods Metric Code class Foo { +1 // comment +1 // comment +1 void Bar() +1 { +1 // lambda function +1 auto a = [](int p) { +1 // ... +1 }; +1 } }; Total: 9 Methods Defined Outside of Types This metric reports the sum of lines that belong to the method declaration and definition. Metric Code // comment Foo class Foo { +1 // comment Bar +1 void Bar(); }; +1 // comment Bar +1 void Foo::Bar() { +1 int i; // comment i +1 } Total: 6

[Top]

Number of Physical Lines metrics measures the total number of lines. It covers all kinds of lines: source code lines, lines with comments and blank lines. This metric measures the number of physical lines that belong to types. It includes comments that precede the types. All nested types are reported separately, thus lines of nested types belong to the nested type only. In the 'Nested types' example, separate values are reported for class Foo and class Bar. Anonymous types belong to the closest regular (nested or not) type. In the 'Anonymous Types' example part, class Foo has 10 lines and no other type is reported.

10.1.3

Metric Code // comment // comment Foo class Foo { // comment Bar void Bar() { } }; Nested Types Metric for Metric for Code class Foo class Bar +1 // comment Foo +1 class Foo +1 { +1 void foo(); +1 +1 // comment Bar +1 class Bar +1 { +1 void bar(); +1 }; +1 }; Total: 6 Total: 5 Anonymous Types Metric for Foo Code +1 class Foo +1 { +1 void foo(); +1 union +1 { +1 long ul; +1 int ui; +1 }; +1 }; Total: 10 Types Containing Methods Defined Outside of a Type The lines of methods defined outside of a type belong to the type. Metric Code +1 // comment Foo +1 class Foo +1 { +1 // comment Bar +1 void Bar(); +1 }; +1 // comment Bar +1 void Foo::Bar() { +1 int i; // comment i +1 } Total: 10

[Top]

The following metric count the number of private members of types. The following members are counted: - fields - constructors - methods - nested types - enumeration constants from anonymous enumerations

v10.1.3

Metric Code class Foo { private: +1 Foo(); +1 void foo(){} +1 int mem; +1 class Bar { }; enum { +2 E1, E2 }; }; Total: 6

[Top]

The following metric count the number of protected members of types. The following members are counted: - fields - constructors - methods - nested types - enumeration constants from anonymous enumerations

v10.1.3

Metric Code class Foo { protected: +1 Foo(); +1 void foo(){} +1 int mem; +1 class Bar { }; enum { +2 E1, E2 }; }; Total: 6

[Top]

The following metric count the number of public members of types. The following members are counted: - fields - constructors - methods - nested types - enumeration constants from anonymous enumerations

v10.1.3

Metric Code class Foo { public: +1 Foo(); +1 void foo(){} +1 int mem; +1 class Bar { }; enum { +2 E1, E2 }; }; Total: 6

[Top]

This metrics counts the number of return statements in a method. Other exit points (e.g., throw statements) are not counted.

v10.1.3

Methods with a large amount of return statements are more difficult to debug and may be a sign of poor organization.

Example C/C++ Metric Code int foo(int i) { if(i > 0) { +1 return 1; } else if (i < 0) { +1 return -1; } else { +1 return 0; } } Total: 3 Example C++ Metric Code class Exception{}; class Foo { public: int foo(int i) { if(i > 0) { throw Exception(); } +1 return 1; } }; Total: 1

[Top]

Number of Source Lines metrics measures the number of lines with source code. It covers lines that have code and lines that are not comments only (or commented-out code). This metric measures the number of source code lines in file.

10.1.3

Metric Code // comment +1 struct Foo +1 { +1 int i; +1 }; +1 int foo(int j) { /* comment */ +1 int i; /* comment */ +1 if ((i + j) > 0) { +1 return 1; +1 } +1 } Total: 10

[Top]

Number of Source Lines metrics measures the number of lines with source code. It covers lines that have code and lines that are not comments only (or commented-out code). This metric counts the number of source code lines that belong to methods.

10.1.3

Metric Code // comment Foo class Foo { public: // comment foo +1 int foo(int j) { /* comment */ +1 int i; /* comment */ +1 if ((i + j) > 0) { +1 return 1; +1 } +1 } }; Total: 6

[Top]

Number of Source Lines metrics measures the number of lines with source code. It covers lines that have code and lines that are not comments only (or commented-out code). This metric counts the number of sources code lines that belong to types.

10.1.3

Metric Code // comment Foo +1 class Foo +1 { +1 public: // comment foo +1 int foo(int j) { /* comment */ +1 int i; /* comment */ +1 if ((i + j) > 0) { +1 return 1; +1 } +1 } +1 }; Total: 10

[Top]

This metric counts the number of types per type. The following elements count as types: - class - structure - union

10.1.3

Metric Code +1 class Foo { }; +1 struct Bar { }; +1 union Baz { }; enum En { }; Total: 3

[Top]

This metric counts the number of methods in the class plus the number of methods called by the class. Calls to the methods of the same class or its base classes are not counted.

v10.1.3

Metric for Foo Metric for Bar Code class Foo { public: +1 Foo(); +1 void foo(); +1 void foo(int); }; class Bar { public: +1 Bar(); +1 void bar(int); }; Bar::Bar() { +1 Foo mFoo; // implicit call of constructor +1 mFoo.foo(); } void Bar::bar(int i) { Foo mFoo; // implicit call of the same constructor +1 mFoo.foo(i); } Total: 3 Total: 5

[Top]

Introduced by Thomas McCabe, cyclomatic complexity measures the number of linearly independent paths through which messages can pass.The result of this measurement is a single ordinal number that can be used to compare the cyclomatic complexity across programs. A program module's complexity can also be interpreted as the cost of producing test cases for the code. Methods with low cyclomatic complexity imply that decisions are deferred through message passing--though this does not imply that a method is not complex or intricate. Methods with a high complexity tend to be more difficult to understand, maintain, and test; thus complex methods adversely affect an application's reliability. The metric is computed by counting the number of decisions in the flow graph and incrementing the number be one, as in the following formula: C = Number of decisions + 1 If C is greater than or equal to 10, industry standards recommend splitting the method since the more complex the program the harder it is to test and comprehend. For all variations of CC metric each occurrence of the following expressions count as a decision point: - if, for, while, do-while, case (non-empty), catch - conditional expression a?b:c inside if, for, while, do-while condition This metric measures the Strict Cyclomatic Complexity according to the following formula: SCC = Number of decisions + 1 Every condition and switch case increases the metric value. Boolean operators inside conditions, e.g., && or ||, are also treated as a condition and increase the metric value.

10.1.3

Metric Code +1 void foo() { int i, j, k; +1 if(i > 0) { //... +1 } if(i > 1) { // ... } else { //... } +1 for(i = 0; i < 10; i++) { //... } +1 while(i > 0) { //... } do { //.... } +1 while(i > 0); +2 if(i > 0 && j > 0){ //... } +2 if(i > 0 || j > 0){ //... } +1 k = (i > 0) ? 1 : 0; switch(i) { +1 case 0: +1 case 1: i++; +1 case 2: i--; default: i = 10; } } Total: 14

[Top]

This metric calculates the sum of Strict Cyclomatic Complexity (see METRIC.SCC) of methods of a class.

v10.1.3

The weighted methods of class (WMC) metric is the sum of the complexities of all type methods where the number of methods and the complexity of the methods involved is a predictor of how much time and effort is required to develop and maintain the type. WMC measures usability and reusability via strict cyclomatic complexities by summing METRIC.SCC of the declared methods and constructors of type. A type with a low WMC usually points to greater polymorphism, while a type with a high WMC indicates that the type is complex and therefore harder to reuse and maintain.

Metric Code class Foo { public: void foo(); +1 void foo(int i, int j, int k) { +1 if(i > 0) { //... +1 } if(i > 1) { // ... }else { //... } +1 for(i = 0; i < 10; i++) { //... } +1 while(i > 0) { //... } do { //.... } +1 while(i > 0); } }; +1 void Foo::foo() { int i, j, k; +2 if(i > 0 && j > 0){ //... } +2 if(i > 0 || j > 0){ //... } +1 k = (i > 0) ? 1 : 0; switch(i) { +1 case 0: +1 case 1: i++; +1 case 2: i--; default: i = 10; } } Total: 15