How Embedded Coder Resolves MISRA C 10.x Rule Violations
In standard C, data types in expressions rely on the compiler for implicit promotions or conversions, which can lead to unexpected results or data loss. The MISRA™ guidelines address this by enforcing these conversions to be explicit to ensure safer and more predictable behavior. MISRA C defines a concept of essential types, that classify data types into categories which help to prevent unsafe conversions in the C code. For more information, see Essential Type Model Used in MISRA C Rule Checking (Polyspace Bug Finder).
Embedded Coder® generates explicit casts in the generated code to comply with MISRA C:2012 and MISRA C:2023 10.x rules (Essential type model) when the
Casting mode configuration parameter is set to
Standard Compliant. These rules require that code explicitly
preserve essential type categories when operands participate in expressions or assignments.
The generated casts improve MISRA compliance by making type conversions explicit and prevent data loss or
undefined behavior. Although some casts may appear redundant in standard C, they are
necessary for MISRA compliance.
Casts for Constants
In standard C, integer constants exist only for int,
unsigned int, long, or long
long, which are typically 32-bit or 64-bit in size. It is not possible to
directly represent smaller width types such as char or
short. MISRA requires constants to be represented using the Signed Type of
Lowest Rank (STLR) or Unsigned Type of Lowest Rank
(UTLR). The following table shows how Embedded Coder generates explicit casts for constants to achieve MISRA compliance.
| Expression | Standard C | Embedded Coder code | Explanation |
|---|---|---|---|
| 8-bit signed | int8_T s8 = 1; | int8_T s8 = (int8_T)1; | In standard C, the constant 1 is of type
int. Embedded Coder adds an explicit int8_T cast to
1 to represent it using STLR. |
| 8-bit unsigned | uint8_T u8 = 1U; | uint8_T u8 = (uint8_T)1U; | In standard C, the constant 1U is of type
unsigned int. Embedded Coder adds an explicit uint8_T cast to
1U to represent it using UTLR. |
| 16-bit signed | int16_T s16 = 128; | int16_T s16 = (int16_T)128; | In standard C, the constant 128 is of type
int. Embedded Coder adds an explicit int16_T cast to
128 to represent it using STLR. |
| 32-bit unsigned | uint32_T u32 = 1U; | uint32_T u32 = (uint32_T)1U; | In standard C, the constant 1U is of type
unsigned int. Embedded Coder adds an explicit uint32_T cast to
1U to preserve the essential unsigned type and
prevent unintended promotions. |
These explicit casts over constants, even with U suffix, are
necessary to ensure the correct essential type and prevent implicit promotions. These
casts are not redundant and they explicitly enforce the essential type and prevent
violations of MISRA rules 10.5 and 10.8. Without these casts, C would promote the constant to
int or unsigned int, causing type mismatch in
the expressions.
Resolving Booleans
In standard C, Boolean expressions are evaluated as int.
MISRA requires expressions that are essentially Boolean to be represented
explicitly as Boolean types. Embedded Coder generates conditional expressions to convert Boolean values to their
essential types and prevent implicit integer conversions. Logical expressions
(&&, ||, !) returns
int in standard C. MISRA requires that these expressions evaluate to an essentially Boolean type.
Embedded Coder generates conditional comparisons to ensure that operands and results are
explicitly Boolean. The following table shows how Embedded Coder casts Booleans to their essential types.
| Expression | Standard C | Embedded Coder code | Explanation |
|---|---|---|---|
| Char negation | b1 = !c; | b1 = (c == '\0'); | In standard C, !c returns int.
Embedded Coder generates explicit comparison with zero to produce a
Boolean result. |
| Integer logical | u32 = u16 | 2U; | u32 = (uint32)(uint16)(u16 | (uint8)2U); | In standard C, 2U is promoted to
int for bitwise operations. Embedded Coder casts it to uint8 and then to
uint16 before assigning the result to
uint32 to ensure explicit and compliant type
conversions. |
| Float test | b4 = dbl; | b4 = (dbl != 0.0) ? 1 : 0; | In standard C, assigning a floating-point value to a Boolean uses implicit conversion. Embedded Coder generates an explicit comparison to zero to produce a Boolean result. |
| Pointer test | b5 = !ptr; | b5 = (ptr == NULL); | In standard C, !ptr returns an
int. Embedded Coder generates explicit null-pointer comparison to produce a
Boolean result. |
These conversions ensure logical expressions use Boolean types explicitly and prevent violations of MISRA rules 10.1 and 10.3.
Casts for Enumerations
In standard C, enumeration operands use implementation-defined integer types. Using them directly in arithmetic or logical operations can cause unpredictable behavior. MISRA requires that enumeration operands not be used as numeric values without explicit conversion. Embedded Coder resolves such violations by casting enumeration operands to their corresponding essential signed or unsigned type depending on their value range.
| Expression | Standard C | Embedded Coder code | Explanation |
|---|---|---|---|
| Unary negation | result = -myEnum; | result = -(int32_T)myEnum; | In standard C, enumeration constants are represented by
implementation-defined integer types. Embedded Coder generates an explicit int32_T cast to
ensure defined signed arithmetic behavior. |
| Addition | x = x + myEnum; | x = x + (int32_T)myEnum; | In standard C, enumeration operands may implicitly convert to
int. Embedded Coder generates an explicit int32_T cast to
achieve predictable arithmetic behavior. |
| Enum to Boolean | b = myEnum; | b = ((int32_T)myEnum != 0) ? true : false; | In standard C, assigning an enum to a Boolean performs implicit integer conversion. Embedded Coder generates an explicit comparison to zero to ensure the result is Boolean. |
Enum casts are added only when the operand participates in arithmetic, bitwise, or logical operations. These conversions make enumeration based operations predictable and prevent violations of MISRA rules 10.1, 10.3, and 10.8.
Casts for Composite Expressions
Composite expressions often combine operands of different essential types. In standard C, such operands undergo integral promotions and usual arithmetic conversions, which can cause unintended type mismatches. Embedded Coder generates explicit casts to preserve essential type consistency. The following table shows how Embedded Coder generate casts for composite expressions to their essential types.
| Expression | Standard C | Embedded Coder code | Explanation |
|---|---|---|---|
| Boolean + int | result1 = b + int32Var; | result1 = (b ? (int8_T)1 : (int8_T)0) +
int32Var; | In standard C, Boolean operand b is promoted to
int before arithmetic. Embedded Coder converts the Boolean to an explicit numeric equivalent of
its essential type to preserve type consistency. |
| Boolean / float | result2 = b / float32Var; | result2 = (b ? 1.0 : 0.0) / float32Var; | In standard C, Boolean b is promoted to
int. Embedded Coder generates an explicit float equivalents
(1.0 or 0.0) to prevent
implicit promotion and ensure predictable arithmetic. |
These explicit casts prevent violations of MISRA rules 10.4, 10.6, and 10.8.
Casts for Shift Expressions
In standard C, shift operators do not apply the usual arithmetic conversions. The left
operand determines the result type, while the right operand is promoted to
int, which can lead to negative shift counts or undefined
behavior. MISRA requires the right operand to be unsigned and the
result to retain the left operand’s essential type. The following table shows how
Embedded Coder generate casts for shift operands.
| Expression | Standard C | Embedded Coder code | Explanation |
|---|---|---|---|
| Left shift with signed RHS | u16 = u16 + (1U << u32); | u16 = u16 + (uint16)((uint8)1U <<
u32); | In standard C, 1U is promoted to
int for shift operations. Embedded Coder casts it to uint8 first and then to
uint16 to prevent invalid shifts. |
| Right shift with signed RHS | u64Var = u64Var >> s8; | u64Var = u64Var >> (uint32_T)s8; | In standard C, s8 is promoted to
int. Embedded Coder generates an explicit uint32_T cast to
predict the shift count. |
| Signed 64-bit shift | s64Var = s64Var >> s64Var; | s64Var = s64Var >> (uint64_T)s64Var; | In standard C, shifting a signed 64-bit value by is
implementation-defined. Embedded Coder casts the shift amount to uint64_T to
enforce the predictable behavior. |
These conversions ensure shift operations use unsigned operands and prevent violations of MISRA rules 10.1, 10.6, and 10.7.
See Also
MISRA C:2012 Compliance Summary Tables | MISRA C:2023 Compliance Summary Tables