14.1 There shall be no unreachable code

6.14 Control Flow

Moderators: misra-c, david ward

Locked
Frank Haug
Posts: 4
Joined: Mon Oct 15, 2007 8:05 am
Company: none
Location: Germany

14.1 There shall be no unreachable code

Post by Frank Haug » Wed Oct 24, 2007 8:27 am

The wording of 14.1 does not clarify the issue clear enough. I've discussed with several experienced persons and the common of these discussions is, that the questions only can be resolved, if someone ADDS personal interpretations. That cannot be the intension of a rule (text).

Firstly, \"defensive programming\" is not a misra rule. In my opinion this is a severe lack in/on the misra rule set. Although not explicitly defined its used in the rule text of 14.1 and its used in a confusing way: \"Code that can be reached but may never be executed is excluded from the rule (e.g. defensive programming)\".

In my tries to understand this, I refactored this sentence on following part (and nobody out of my discussions with Developers and QA Managers could give me an answer on that):

What is \"code, that can be reached but (may) never be executed\" ?

The provided example does not answer this question, because it shows code that \"exists but never will be reached\".

Maybe it helps to concretesize my intention when I re-word above sentence as follows: \"Is it possible, that code can be reached but not executed ?\"

Thanks in advance

Frank

mmeyer
Posts: 1
Joined: Mon Oct 17, 2005 11:23 am
Location: dSPACE GmbH, Paderborn, Germany

Re: 14.1 There shall be no unreachable code

Post by mmeyer » Tue Oct 30, 2007 4:42 pm

Frank Haug wrote:The wording of 14.1 does not clarify the issue clear enough. I've discussed with several experienced persons and the common of these discussions is, that the questions only can be resolved, if someone ADDS personal interpretations. That cannot be the intension of a rule (text).

Firstly, "defensive programming" is not a misra rule. In my opinion this is a severe lack in/on the misra rule set. Although not explicitly defined its used in the rule text of 14.1 and its used in a confusing way: "Code that can be reached but may never be executed is excluded from the rule (e.g. defensive programming)".

In my tries to understand this, I refactored this sentence on following part (and nobody out of my discussions with Developers and QA Managers could give me an answer on that):

What is "code, that can be reached but (may) never be executed" ?

The provided example does not answer this question, because it shows code that "exists but never will be reached".

Maybe it helps to concretesize my intention when I re-word above sentence as follows: "Is it possible, that code can be reached but not executed ?"

Thanks in advance

Frank
My understanding of the rule is as follows:

The reachability of a code portion is given by the logic of the implementation in a given context. This is typically the body of a function. Here, reachability of a statement can be determined by evaluating the logic of control flow and its conditions.

However, when a function is used, all calls to it may use input values such that a particular portion of the code is not executed. An example that can often be found is the following: A pointer is passed to a function to access some data. In the function, before accessing the data, it is checked whether the pointer points to a valid address (e.g. is not NULL). If a NULL pointer is detected, an error is raised somehow.

The callers of the function however, check if their parameters have valid values and do not call the function if they don't. This means that during normal program execution the error code is reachable but is never executed. Nevertheless it could happen that the function may be called with a valid pointer but due to a failure (electrical hazard or another parallel process/thread memory access) the parameter value is cleared and the pointer is set to NULL or more likely, another caller is implemented that does not check its parameters (think of library functions).

The difference to unreachable code caused by control logic is the ability for the compiler to eliminate an unreachable statement during compilation such that is no longer possible to execute it. Depending on the analysis performed by the compiler, the situation sketched above could also be analysed to some extend.

May be this could help in understanding the rule!

Martin

misra-c
Posts: 566
Joined: Thu Jan 05, 2006 1:11 pm

Post by misra-c » Tue Dec 11, 2007 11:42 am

Unreachable code:
Code is unreachable if the syntax does not permit the code to be accessed.

Infeasible code:
Code is infeasible code if the syntax allows it to be accessed but the semantics ensure that it cannot be reached whatever input data is provided.

Dead code:
Code is dead if it reachable and feasible, but has no effect on the outputs.

This rule is only concerned with Unreachable code.

Defensive code is either unreachable or infeasible.
---
Posted by and on behalf of
the MISRA C Working Group

Frank Haug
Posts: 4
Joined: Mon Oct 15, 2007 8:05 am
Company: none
Location: Germany

Post by Frank Haug » Mon Jan 14, 2008 6:32 am

A bright British (1) wrote \"The argument of this book – which again, surely, can only convince you insofar as what I say fits with what you know.\" (2)

According to this I thought me to know too less, because I do not understand the MISRA committee's view at all (Rule 14.1 and last contribution of 2007-12-11). This means I went to school again: Google and and electronic documents that enclose a lot of documents of todays C and C++ gurus, but publications of non-guru publishers as well. The result: \"infeasible code\" does not exist in a huge amount of IT related publications.

I'd been irritated. Anyone of us seem to be wrong here.

What are the facts ? We have reachable code and not reachable code. The MISRA committee tells us that there may be \"code, that can be reached but (may) never be executed\" (Rule 14.1). And in my request for clarification, I get additional remarks that enhance the wording confusion speaking about \"infeasible code\" and \"dead code\".

Several days I thought about how to answer on such absurd things appropriately. Firstly I thought to add some kind of \"living code\" (e.g. the brother of \"dead code\"), or \"happy code\" (the sister of ...). But this does not solve our problems pursuing to more quality in software solutions. But the MISRA committee doesn't resolve the problems either. MISRA committes' wordings are referenced nowhere, neither marked with an authors name. This works against all accepted academic standards in doing a serious scientific oriented job. It's a lack of respect against all well educated and experienced quality managers and software developers all over the world, that are forced to meet their decisions DAILY and not in 4, 5 or 6 years (when we may get a reworked MISRA publication).

I solved the problems for myself by re-structuring the related issues:

- - - - - - - - - -

I delete MISRA Rule 14.1 and substitute it with two others:

not MISRA 2004 - extension 1: avoid unreachable code - advisory
===============================================================

reason: there only can be reachable code or unreachable code. Unreachable code is not safety critical, but it reduces transparency and maintenance, therefore it should be eliminated. Because unreachable code
is not primarily dangerous, I mark it as \"advisory\".

not MISRA 2004 - extension 2: Defensive Programming - mandatory
==============================================================

always take
*) a default statement in a switch
*) a final else branch (in \"if - else if - else if - else\" (14.10) ... not necessary in \"if only\") EXCLUSIVELY to catch error conditions.

reason: changing code in an other part of the translation unit (maybe later) may lead into the default or final else branch and always should be caught.
(also see \"6.15 Switch Statements -> Switches, default, and enums!\"
Posted: Wed Jan 09, 2008 5:12 pm, by George Brown).

- - - - - - - - - -

Out of my view these two extensions cover a lot of possibilities and allows clear decisions in coding and coding evaluation. But I've forgotten an important aspect: I have to word a deviation procedure for refusing MISRA Rule 14.1: I fill it with above argumentation and a reference on this discussion thread. Now I'm MISRA compliant again.

Thanks for the recipients patience. Refinements and critisism are appreciated.

Frank (Haug), [email protected], Stuttgart, Deutschland

----------------------------------
(1) Gregory Batseon, son of the geneticist William Bateson and husband of the famous Margaret Mead
(2) Mind and Nature, out of chapter \"science never proof anything\"

BTW:
Out of 20 years of working together with informatics and mathematics, it appears to me that some of them could profit from
the smallest unit is a difference (GB)

Frank Haug
Posts: 4
Joined: Mon Oct 15, 2007 8:05 am
Company: none
Location: Germany

Post by Frank Haug » Mon Jan 14, 2008 7:39 am

could prfit from lessons of this great British, a person, who applied cybernetic ideas on living systems centuries before the first PC could be bought. Useful could be - e.g. - to get familiar with Bateson's ideas in chapter 4.8 out of \"steps to an ecology of mind\" : the locial categories of learning and communication.
</END OF BTW> Frank
the smallest unit is a difference (GB)

misra-c
Posts: 566
Joined: Thu Jan 05, 2006 1:11 pm

Post by misra-c » Mon Jan 14, 2008 3:46 pm

Hi Frank,

MISRA-C postings indicate guidance which is agreed by the MISRA-C committee, and in most cases reflects changes or direction which will subsequently be included in Technical Corrigenda, or subsequent full document releases. This Forum is used in the first instance to clarify issues arising from previous documents. As such, we use the name MISRA-C to show that it IS the agreed view of the committee.

Individual members of the committee may also post, but are doing so in a personal capacity. Such personal postings do not form part of the official direction and interpretation of the rules.

I have amended the signature to add an e-mail contact and current chairman's name.

Gavin
---
Posted by and on behalf of
the MISRA C Working Group

Gavin McCall
Posts: 72
Joined: Mon Sep 13, 2004 9:24 am

Post by Gavin McCall » Mon Jan 14, 2008 4:06 pm

Hi Frank,
Rule 14.1 There shall be no unreachable code.
The rule is about not having unreachable code.

Or

You shall only have reachable code.

There are a few cases in C in which valid syntax can give a sequence of statements in which one (or more) statements CANNOT be reached and executed. See mc2_1401.c in exemplar suite. These are unconditional control flow changes which cause the subsequent statements are unreachable. I.E. break, goto, return, if(0), if(!1).

This rule is NOT about ANY reachable code, which may include code that only executes under \"adverse\" conditions (i.e. defensive programming). No form of reachable code is excluded by this rule.

The example is an example of unreachable code in the syntax of a switch statement. It is NOT an example of defensive programming. Subsequently, TC1 enforces the syntax of a switch statement, so this example would violate Rule 15.0 – Switch Statement syntax.
not MISRA 2004 - extension 1: avoid unreachable code - advisory
===============================================================

reason: there only can be reachable code or unreachable code. Unreachable code is not safety critical, but it reduces transparency and maintenance, therefore it should be eliminated. Because unreachable code is not primarily dangerous, I mark it as \"advisory\".
This replacement rule assumes that you have a definition of unreachable.

While the compiler is not confused, having any text which appears to be valid code, but is omitted from the program risks the danger that the human reader believes that code to be executed. The human then draws incorrect assumptions from the text. If the conclusion affects the safety of the system, this is critical. Therefore avoid this risk by the mandatory removal of unreachable code.
not MISRA 2004 - extension 2: Defensive Programming - mandatory
==============================================================

always take
a) a default statement in a switch
b) a final else branch (in \"if - else if - else if - else\" (14.10) ... not necessary in \"if only\") EXCLUSIVELY to catch error conditions.

reason: changing code in an other part of the translation unit (maybe later) may lead into the default or final else branch and always should be caught. (also see \"6.15 Switch Statements -> Switches, default, and enums!\" Posted: Wed Jan 09, 2008 5:12 pm, by George Brown).
But
a) is required under Rule 15.3
b) is required under Rule 14.10, in all cases and not \"Exclusively to catch error conditions\".

What you have written under extension 2 is NOT part of this rule. Rule 14.1 is saying nothing about reachable defensive code.

Gavin
Gavin McCall
Personal view only.

Lundin
Posts: 70
Joined: Mon Dec 10, 2007 1:57 pm

Post by Lundin » Tue Jan 15, 2008 8:00 am

An example of code that can be reached but may never be executed: interrupt service routines written as defensive programming.

There is no way for a compiler (or static analysis tool) to predict which hardware interrupts that will occur in a system. Interrupts are not covered by the C standard nor explicitly by MISRA-C, yet there are few (if any) processors that lack interrupts. An interrupt must by definition be marked as reachable in some way, otherwise the code would be optimized to remove the interrupt, since it is never called by the code, but by the hardware.

In a safety-critical system, it is good defensive programming-practice to implement an interrupt service routine for every interrupt that is supported by the hardware, no matter if you will use that functionality or not. Because if the system is exposed to EMI, damaged external hardware, silicon bugs in the processor etc etc, it may very well execute those interrupts still. They should therefore be handled, so that the system may detect incorrect behavior and enter a fail-safe mode.

Such interrupt service routines are reachable, but will never be executed as long as the system works properly.

---

Though I think a lot of the confusion here comes from reading the document in English and not in \"Standardish\". In Standardish, the word \"shall\" is normative while \"may\" usually means \"may or may not\".

George Brown
Posts: 10
Joined: Fri Jul 13, 2007 1:13 pm

Post by George Brown » Tue Jan 15, 2008 10:34 am

Embedded control software contains many things outside the scope of the language.

Interrupt Service Routines (ISR) are an example of code which IS reachable, but outside the definition of C. Compliers often have extensions like \"__interrupt\" to flag this.

Defining code for ALL ISRs is a good idea.

Within the file that the ISR is defined, it will appear to be an external function.

Across all files in the system, ISRs may appear to be uncalled global functions, although they may be referenced by the code which sets up the vector of ISRs.

Is there a MISRA Rule which bans uncalled global functions?

Another practice is to place trap code in unused ROM. Should the program counter be corrupted to point into unused ROM, the unused ROM contains NOP (no-operation) instructions and is incremented thru until the trap is reached. This is particularly useful if having reset, it is not possible to determine the cause. The trap could store the cause prior to the reset.

Examination of the assembler and/or final memory image is required to confirm correct build.

I treat this rule as being limited to statements withinin functions which are unconditionally bypassed by preceding statements. The examples in the exemplar suite appear to support this view.

George
Embeded Software developer since 85.

mishak
Posts: 10
Joined: Thu Jun 21, 2007 3:58 pm

Dead Code

Post by mishak » Tue Jan 15, 2008 10:42 am

Hi Frank,

Dead code is simply code that is executed, but which is not needed as it does not affect program output. For example:

Code: Select all

int32_t x

x = 12;   // This is dead code, as the assigned value is never used.
x = 15;
use ( x );
Dead code (although not covered by this rule) indicates a possible error in the code. e.g. was the dead code above supposed to initialise some other object?

Lundin
Posts: 70
Joined: Mon Dec 10, 2007 1:57 pm

Re:

Post by Lundin » Tue Jan 15, 2008 12:09 pm

George Brown wrote:Is there a MISRA Rule which bans uncalled global functions?
No, though there are is rule 8.2 enforcing an explicit linkage specifier (extern or static). The ISR definition should always be static, no other code module in the system could be interested of it. The ISR may however have a function prototype, hopefully, if the compiler allows that. If it doesn't, the ISR doesn't conform to rule 8.1 (must have a prototype), strictly speaking. With a good C compiler, you should only need a deviation from MISRA-C 1.1 (ISO C) when using interrupts.

Anyway, I would treat the calling of an ISR as an allowed exception to rule 14.1. All code within the ISR should naturally still be subject to the rule.

Locked

Return to “6.14 Control Flow”