Search code examples
cmisra

MISRA C:2012 Rule 14.4


As per the MISRA rule The controlling expression of an if statement and the controlling expression of an iteration-statement shall have essentially Boolean type

#include <stdbool.h>
#include <stdlib.h>

void foo(void){
    int i = 0;

    if(i){}              /* Non-compliant - int32_t is not boolean */

    if(i != 0){}         /* Compliant */

}

I am not able to understand how can it lead to a problem to use just the value .Why with if only adding a boolean expression is treated as good practise . Any insight will be helpful


Solution

  • The rationale is provided with the rule: strong typing. The controlling expression should be essentially boolean type. The result of the equality, relational etc operators is to be regarded as essentially boolean, whereas showing in an int or pointer without an operator means that the expression is of the used type.

    (As a side-note, this may be important for compatibility with C++ where a lot of operators actually return a bool, and may be overloaded with an operator function returning bool.)

    The main reason is however not provided by MISRA, and that is self-documenting code. if(ptr != NULL) can only be a comparison of a pointer against NULL. No room for misunderstandings. if(ptr) could either be a comparison against NULL, or it could be an accidental slip of the finger and the programmer actually meant if(*ptr). Also, if the pointer has some cryptic name, it isn't obvious what if(xyz) does, but it is obvious what if(xyz != NULL) is.

    This rule also prevents bugs such as if(func) where if(func()) was intended. Keep in mind that a lot of the MISRA rules are there for the benefit of a static analyser.


    Regarding strong typing, consider this example:

    #include <stdio.h>
    #include <stdbool.h>
    
    int main (void)
    {
      int x = false;
      x = ~x;
    
      if(x)
      {
        puts("x is true");
        if(x!=true)
        {
          puts("but x is not true\n");
        }
      }
    
      bool y = x;
    
      if(y)
      {
        puts("y is true");
        if(y==true)
        {
          puts("I swear, y is really true");
        }
      }
    }
    

    Output:

    x is true
    but x is not true
    
    y is true
    I swear, y is really true