Maybe the concept of composite cast sounds quite weird, so let me clarify it: *A composite expression is a non-constant expression which is the direct result of a composite operator.*

For example, a composite macro can be defined as follow:

Get_Translated_Aux() returns a uint8 value…so, the today question is: Which is the type of FAN_HYSTERESIS_AUX?

If you said uint8, you are right because C always uses the largest type in a assignment, in this case uint8, which can express larger numbers than sint8 by definition. This selection is called “Integer promotion”.

Integer Promotion is *the silent conversion of smaller integral types when an expression is evaluated in an operation*. For example:

The answer of the previous code is uint16, “C” will be promoted to be uint16 and then both uint16 will convey to a uint16 result.

Moreover, there is a concept called “Balancing” which is similar than integer promotion, but it takes place when there are two different operands. Balancing will convert both operands to a common type to perform further operations.

The balancing sets of rules are as follow:

- If either operand is
*long double*, the other operand is converted to*long double*. - Otherwise, if either operand is
*double*, the other is converted to*double*. - Otherwise, if either operand is
*float*, the other is converted to*float*. - Otherwise:
- The integral promotions are performed on both operands
- If either operand is
*unsigned long int*the other is converted to*unsigned long int* - Otherwise if one operand is
*long int*, and the other operand is*unsigned int*:- If a
*long int*can represent all values of an*unsigned int*, the unsigned int is converted to*long int*. - Otherwise both are converted to
*unsigned long int*

- If a
- Otherwise if one operand is
*long int*the other is converted to*long int* - Otherwise if either operand is
*unsigned int*the other is converted to*unsigned int*. - Otherwise, both operands have type
*int*

So, let’s define an example to make balancing concept easier. In this example, we are going to use FAN_HYSTERESIS_TEMP to compare if an input temperature is in range to turn on an output load:

Remember than FAN_HYSTERESIS_TEMP operands were promoted to uint8, so the first reflection might be to cast the composite expression to sint16 as we might have large temperature values.

This is a bad approach since MISRA Rule 10.6 and 10.7 forbid **that a value of a composite expression is used in usual arithmetic conversion and even more being casted to a wider essential type.** This is because the sequence of arithmetic operations within an expression must be conducted in the same essential type to avoid confusion to the developer.

Imagine a sequence of arithmetic operations as follow:

**u32a + u16b + u16c;**

But what if we add a composite expression? The composite expression will make harder to track down the result type. For example, the following composite expression requires an implicit conversion to uint32.

**(u16a + u16b ) + u32c **

The correct approach is to perform an artificial integer promotion to the same essential type; that is to cast the promoted type (uint8) to an even higher type to force the result to be sint16, and now the conditional does not require any cast:

This code won’t yield to any QAC warning.

## To Remember

- Use composite expression carefully in sequences of arithmetic operations.
- Remember implicit integer and balancing concepts to track down types in composite expressions.
- Avoid explicit and implicit conversions of composite expressions.
- Force artificial casting from the root of the composite expression if a cast is really required.