MISRA Discussion Forums

Full Version: Booleans and the unterlying type
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
There are no boolean types in C and I assume that rule 10.x also apply to boolean expressions. The question now is how to make
boolean expressions compliant to these rules.
If there are variables boolU8 and boolS8 which are of type unsigned char and signed char are represent boolean values, and assignment
will require an explicit cast:
boolU8 = (uint8)boolS8;
No problem here.

Boolean operators &&, || and ! yield a result of type "int" (MISRA-C:2004 page 37 3rd paragraph), which confuses me a little bit,
because I expected the guideline to specify an "underlying type" instead of a real type.
So to have a simple assignment like
boolU8 = c && d;
compliant, I have to downcast to the result to uint8, which requires a temporary variable (according to rule 10.3):
int _t = c && d;
boolU8 = (uint8)_t;

The is no more safe than the simple assignment, a lot less readable and involves the plain type "int", which violates rule 6.3 (typedefs
should be used in place of the basic types).

I did not find anything on this subject in the technical corrigendum, nor does the entry in the glossary on "boolean expressions" help
with type casting.

Any thoughts ?
After some thinking about the issue, I came to the conclusion that the
underlying type of a &&, || or ! is determined in the same way as for
arithmetic operations, and the previous example needs to be clarified
a little bit:
boolU8 = boolU8X && boolU8Y;
is fully compliant, whereas
boolU8 = boolU8X && boolS8Y;
is not compliant, one of the operands needs to be casted, e.g.:
boolU8 = boolU8X && (uint8)boolS8Y;

However, the problem with relational operators remains:
boolU8 = a > b;
What is the underlying type of the result of a >, >=,
The concept of the "effectively Boolean" type is discussed in MISRA-C:2004 Appendix E.

According to this concept, there is no need to use an intermediate variable of type int to hold the result of a Boolean, equality or relational operator. Your example:

int _t = c && d;
boolU8 = (uint8)_t;

could therefore be written as:

boolU8 = c && d;

This is permitted according to MISRA-C:2004 Rule 12.6 as amended by Technical Corrigendum 1. It was not permitted according to the original MISRA-C:2004. It may therefore be the case that your checking tool has not incorporated TC1. Your results will also depend on how your checking tool identifies the effectively Boolean type.
May I ask why you are using two different Boolean types, boolU8 and boolS8, in your code?

Dave Banham
Hello Dave,

we are developing a code generator that is supposed to generate code
that complies to MISRA-C:2004. The models of our customers
contain different Boolean types (maybe for historic reasons).

I do not understand how Rule 12.6 influences type casting: it mainly forbids the mixture of Boolean and arithmetic expressions. However, since ANSI-C:1990 does not define a Boolean type, Booleans are represented by arithmetic types and are therefore subject to the rules 10.x.
Rules 10.x deal with arithmetic types only - they are not intended to deal with "Boolean" types.

Since C90 does not have a Boolean type it is, as you state, implemented as an int. Despite this, the intention of MISRA C is to treat Boolean types according to a different set of rules from the arithmetic types. Rule 12.6 (as amended by TC1) states which operations can be applied to objects with Boolean type.