What is the benefit of terminating if … else if constructs with an else clause?

This is the equivalent of requiring a default case in every switch.

This extra else will Decrease code coverage of your program.


In my experience with porting linux kernel , or android code to different platform many time we do something wrong and in logcat we see some error like

if ( x < 0 )
{
    x = 0;
}
else if ( y < 0 )
{
    x = 3;
}
else    /* this else clause is required, even if the */
{       /* programmer expects this will never be reached */
        /* no change in value of x */
        printk(" \n [function or module name]: this should never happen \n");

        /* It is always good to mention function/module name with the 
           logs. If you end up with "this should never happen" message
           and the same message is used in many places in the software
           it will be hard to track/debug.
        */
}

As mentioned in another answer, this is from the MISRA-C coding guidelines. The purpose is defensive programming, a concept which is often used in mission-critical programming.

That is, every if - else if must end with an else, and every switch must end with a default.

There are two reasons for this:

  • Self-documenting code. If you write an else but leave it empty it means: "I have definitely considered the scenario when neither if nor else if are true".

    Not writing an else there means: "either I considered the scenario where neither if nor else if are true, or I completely forgot to consider it and there's potentially a fat bug right here in my code".

  • Stop runaway code. In mission-critical software, you need to write robust programs that account even for the highly unlikely. So you could see code like

    if (mybool == TRUE) 
    {
    } 
    else if (mybool == FALSE) 
    {
    }
    else
    {
      // handle error
    }
    

    This code will be completely alien to PC programmers and computer scientists, but it makes perfect sense in mission-critical software, because it catches the case where the "mybool" has gone corrupt, for whatever reason.

    Historically, you would fear corruption of the RAM memory because of EMI/noise. This is not much of an issue today. Far more likely, memory corruption occurs because of bugs elsewhere in the code: pointers to wrong locations, array-out-of-bounds bugs, stack overflow, runaway code etc.

    So most of the time, code like this comes back to slap yourself in the face when you have written bugs during the implementation stage. Meaning it could also be used as a debug technique: the program you are writing tells you when you have written bugs.


EDIT

Regarding why else is not needed after every single if:

An if-else or if-else if-else completely covers all possible values that a variable can have. But a plain if statement is not necessarily there to cover all possible values, it has a much broader usage. Most often you just wish to check a certain condition and if it is not met, then do nothing. Then it is simply not meaningful to write defensive programming to cover the else case.

Plus it would clutter up the code completely if you wrote an empty else after each and every if.

MISRA-C:2012 15.7 gives no rationale why else is not needed, it just states:

Note: a final else statement is not required for a simple if statement.


Your company followed MISRA coding guidance. There are a few versions of these guidelines that contain this rule, but from MISRA-C:2004:

Rule 14.10 (required): All if … else if constructs shall be terminated with an else clause.

This rule applies whenever an if statement is followed by one or more else if statements; the final else if shall be followed by an else statement. In the case of a simple if statement then the else statement need not be included. The requirement for a final else statement is defensive programming. The else statement shall either take appropriate action or contain a suitable comment as to why no action is taken. This is consistent with the requirement to have a final default clause in a switch statement. For example this code is a simple if statement:

if ( x < 0 )
{
 log_error(3);
 x = 0;
} /* else not needed */

whereas the following code demonstrates an if, else if construct

if ( x < 0 )
{
 log_error(3);
 x = 0;
}
else if ( y < 0 )
{
 x = 3;
}
else /* this else clause is required, even if the */
{ /* programmer expects this will never be reached */
 /* no change in value of x */
}

In MISRA-C:2012, which supersedes the 2004 version and is the current recommendation for new projects, the same rule exists but is numbered 15.7.

Example 1: in a single if statement programmer may need to check n number of conditions and performs single operation.

if(condition_1 || condition_2 || ... condition_n)
{
   //operation_1
}

In a regular usage performing a operation is not needed all the time when if is used.

Example 2: Here programmer checks n number of conditions and performing multiple operations. In regular usage if..else if is like switch you may need to perform a operation like default. So usage else is needed as per misra standard

if(condition_1 || condition_2 || ... condition_n)
{
   //operation_1
}
else if(condition_1 || condition_2 || ... condition_n)
{
  //operation_2
}
....
else
{
   //default cause
}

Current and past versions of these publications are available for purchase via the MISRA webstore (via).

Tags:

C

Misra