DO-178C - Defensive code versus unreachable code
Objective of defensive code is to improve the robustness of the software as mentioned in DO-178C. But “defensive code” is sometimes used as a kind of basket for justifying a portion of unreachable code.
Is unreachable “default case” candidate for defensive code?
Some justify the non-coverage of parts of the code structure by the fact that it is “defensive code”. This rather quick reasoning may potentially hide vulnerabilities. A detailed analysis of each item of uncovered code should be done on a case-by-case basis. For example, did you hear sometimes the argument: the input of the “switch” is an enumerated value so we cannot get to the default case because it never happens ... and, then, we do nothing in the default case since this case cannot happen ...?
Are you sure how to justify, during an audit led by a Certification Authority, that doing nothing is a means to improve the software robustness?
Can a default case doing nothing be considered as a means of robustness?
The reasons that can cause a memory cell to be modified unintentionally exist. Critical application developers should conduct an analysis that would raise a question such as: if, for whatever reason, the input takes an unexpected value, what will the software's behaviour be? This questioning is the actual goal of defensive programming.
If the “default” case does nothing (only a “break” instruction), the code executed after the switch will expect that the treatment of the switch was carried out through a case other than “default”.
The result of the analysis could be, for example:
There is no problem with this operation because ...
This is problematic because the behaviour of the software, after the “switch” could lead to an erroneous behaviour driving a critical failure condition. See example of code extract below.
Analysis outcome examples
In the case a)
If the analysis confirms that the phenomenon is transient or detected further or ... and without functional or safety impact, it is thus possible to live with this default case doing nothing. Note that here, in the case of default, we cannot really talk about “defensive code” but rather “coding best practice” since we do nothing: coding a "default break" or coding nothing is the same from execution perspective since the compiler does not produce object code. Rationale for doing nothing, outcome of the analysis, should be captured somewhere (typically in the detailed design description or/and in the source code as a comment).
In the case b)
In the case b), it will be necessary to consider the treatment to be carried out, for example by treating the case of default as an error, exception, or any other means which will avoid to fall into an erroneous behaviour.
Author: Luc Pelle - System Design Assurance & Certification Manager, PMV Consulting & Services