Page 1 of 1

Rule 10.1: Essentially Boolean operands with & or | bitwise operators

Posted: Tue Oct 08, 2019 12:16 pm
by suruena
Hello,

In the MISRA-C:2012 essential type model, Rule 10.1 ("Operands shall not be of an innappropriate 'essential type'") allows to use essentially Boolean operands with the && and || logical operators, but disallows to use them with the & or | bitwise operators. However, as the && and || logical operators have short-circuit behavior (i.e. lazy evaluation, resulting effectively in an 'if ... else ...' expression), in some situations it may be preferred to use operators with eager evaluation (i.e. both operands are always evaluated, regardless of the value of the first parameter). For example, to avoid jump instructions in the generated code (the timing differences can be a problem for hard real-time systems, or even a side-channel timing attack), or just to make clear to the reviewer that the order of evaluation is not important.

As an essential Boolean can only hold the value 0 or 1, in my opinion it would be safe to allow the use of the & and | bitwise operators with essentially Boolean operands, in addition to the && and || logical operators. It's true that the order of evaluation won't be ensured when using bitwise operators (marked as unspecified behaviour by the standard), however this shouldn't be a problem when using them with just Boolean variables (i.e. instead of function calls returning a Boolean value) or expressions (or even Boolean literals); and futhermore Rule 13.2 already forbids side effects in expressions with multiple evaluation orders. Was the usage of the & and | bitwise operators disallowed with essentially Boolean operands due to problematic situations with the language (like the evaluation order), or either because it is not a typical C idiom? Do you think the usage of these & and | bitwise operators with Boolean operands can be considered safe (at least in some situations)?

Thanks in advance for any answer.

Re: Rule 10.1: Essentially Boolean operands with & or | bitwise operators

Posted: Tue Oct 15, 2019 10:41 am
by misra-c
MISRA C:2012 introduced the idea of essential types in order to provide stricter type checking. It was the intention that boolean objects should not be used where an operand is interpreted as a numeric value. It also prevents the user mistyping & when && was intended.

An essential Boolean object cannot be guaranteed to have the value 0 or 1. It is only guaranteed that 0 is treated as false and non-zero as true.
For example

Code: Select all

(mybool)(isalpha(ch)) 
    // isalpha returns an unspecified non-zero int value for an alphabetic character
    // mybool is an essential boolean type

Therefore

Code: Select all

  if( (mybool)(isalpha('a')) &  (mybool)(isalpha('b'))  // may be True or False - implementation defined
  if( (mybool)(isalpha('a')) && (mybool)(isalpha('b'))  // always True

This applies to essentially boolean type such as C90 "typedef int mybool".
However, a cast to the C99 _Bool will result in a 0 or 1 value, e.g. "typedef _Bool mybool".

Re: Rule 10.1: Essentially Boolean operands with & or | bitwise operators

Posted: Tue Oct 15, 2019 11:00 am
by suruena
Thanks for the clarification. Therefore, the usage of & and | bitwise operators with just _Bool operands can be considered safe?

Re: Rule 10.1: Essentially Boolean operands with & or | bitwise operators

Posted: Wed Nov 27, 2019 11:49 am
by misra-c
You are correct that the usage of & and | on _Bool operands is well-defined and not-implementation defined.

However such code will still violates rule 10.1 which covers other forms of essentially boolean types which do have implementation-defined issues. The MISRA-C working group considers that the use of _Bool as an operand to a bitwise operator is not in the spirit of bitwise operators and likely to be confusing the reader.