froglogic / Blog / MC/DC Coverage and Short Circuit Explained

# MC/DC Coverage and Short Circuit Explained

Modified Condition/Decision Coverage (MC/DC) is a code coverage metric that is referred to in many safety standards as the highest level of quality. It was first defined to provide an intermediate metric between condition and multiple-condition coverage for integrated circuits. Whereas plain condition coverage was considered too simple, the Multiple-Condition Coverage has the drawback of a potential exponential explosion of test cases. MC/DC is a compromise that guarantees a number of test cases that merely grows linearly with the number of conditions, while still achieving a higher level of confidence compared to basic Condition Coverage.
Here is the DO-178C standard definition of MC/DC:
Every point of entry and exit in the program has been invoked at least once, every condition in a decision in the program has taken all possible outcomes at least once, every decision in the program has taken all possible outcomes at least once, and each condition in a decision has been shown to independently affect that decision’s outcome.
A condition is shown to independently affect a decision’s outcome by: (1) varying just that condition while holding fixed all other possible conditions or (2) varying just that condition while holding fixed all other possible conditions that could affect the outcome.
The sentence in bold was added on top of the definition in DO-178B and precisely permits the behavior of a short circuit. The short circuit (also called passive evaluation) does not exist in integrated circuits because it corresponds to a software optimization which consists of skipping the evaluation of some boolean expressions which do not influence the decision outcome. This is why the extension of this definition was not present in earlier versions of the standard.
To understand the short circuit, we can take a small trivial sample “X = A and B”. If we know that A or B is false, the other term of the expression does not need to be evaluated and we directly know that X is false. This has an impact on the expression’s truth table and permits to generate a more compact table:

[su_table]

 A B A and B False – False – False False True True True

[/su_table]

The minus sign (-) is ambiguous in this table because it traditionally means “don’t care”, but for programming languages which implement the short circuit, it means “don’t evaluate”. This is a big difference as the evaluation of an expression can have side effects. Also, due to the fact that the order of evaluation is from left to right, this table is for C, C++ and C#:

[su_table]

 A B A and B False Don’t evaluate False True False False True True True

[/su_table]

Let see a practical sample of the new definition’s impact: If we take the expression “X = ( A or B ) and C” we will get the following truth table:

[su_table]

 A B C (A or B) and C True Don’t evaluate False False False True False False True Don’t evaluate True True False True True True False False Don’t evaluate False

[/su_table]
Let’s take the test vector A=False, B=True and C=True. If we want to find a test vector which toggles B and which accounts for MC/DC coverage we can only choose the last one A=False and B=False because:

1. All other vectors are modifying the other conditions. So A is not allowed to be True and C is not allowed to be False. This is the constraint introduced by the point (1) of the MC/DC definition.
2. The point (2) allows that conditions which have no impact to the output can be ignored. This applied to the test vector A=False and B=False.

Without the point (2), it would be necessary to create a test vector which fits A=False, B=False and C=True which is not possible if it is not allowed to evaluate C.

To be more concrete, let’s analyze a small C++ sample which uses a short circuit and shows us why the new clause (2) applies to it:

```bool log(const char *text)
{
static FILE *f = NULL;
if ((f || f=fopen("logfile.txt","a+")) &amp;&amp; fputs(text, f) != EOF)
{
fflush(f);
return true;
}
else
return false;
}
This code simply opens a log file (if not already opened) and writes text into it.
The truth table of the ‘if‘ statement is:

f
f=fopen(“logfile.txt,”a+”)
fputs(text,f)!=EOF
if statement

True
Don’t evaluate
False
False

False
True
False
False

True
Don’t evaluate
True
True

False
True
True
True

False
False
Don’t evaluate
False

This simple example illustrates why toggling all conditions is not allowed: we use the same test pattern as above: ‘f’=False, ‘f=fopen(“logfile.txt,”a+”)‘=True and ‘fputs(text,f)!=EOF‘=True. Then we decide to only toggle ‘f=fopen(“logfile.txt,”a+”)‘. The test pattern without short cut would be: ‘f’=False, ‘f=fopen(“logfile.txt,”a+”)‘=False and ‘fputs(text,f)!=EOF‘=True. The programmer has used the short circuit facility of C++ to avoid a crash when calling fputs with a NULL pointer. That’s why it is necessary to apply the new clause (2) of the DO-178C and omit the evaluation of ‘fputs(text,f)!=EOF‘.

Sébastien was born in France and studied mathematics and computer science at the ENSEEIHT in Toulouse.

After his studies, he worked on the development of embedded systems (telecommunication and automotive), as well as software development tools (debugger, processor simulator, ASIC analysis tools).
While devoting some of his spare time to the research of testing methods, he created TestCocoon, which is now the base code of Squish Coco.
Sébastien joined froglogic in late 2011.

Related Articles  Code Coverage for VxWorks Applications  Retrieving Code Coverage from ARM Cortex-M Microcontrollers  Measure code coverage on ARM Cortex-M microcontrollers  Coco – How to measure code coverage on embedded systems via CAN Bus

Tags

Code CoverageMC/DCpoweruser