This diagnostic rule is based on the software development guidelines developed by MISRA (Motor Industry Software Reliability Association).
This diagnostic rule is relevant only to C. The C language allows much freedom in casting between arithmetic types. But such implicit conversions can also lead to hidden problems such as loss of sign, value, or precision.
Code example:
void foo()
{
....
uint16_t var_a = 30000;
uint16_t var_b = 40000;
uint32_t var_sum;
var_sum = var_a + var_b; /* var_sum = 70000 or 4464? */
....
}
When you calculate the 'var_sum' variable value an implicit type conversion from the 'uint16_t' type to 'int' occurs. In consequence, the assignment result depends on the 'int' type size.
If 'int' has the 32-bit size, the modulo 2^32 operation is performed, and the expected '70000' value is written to the 'var_sum' variable.
If 'int' has the 16-bit size, the modulo 2^16 operation is performed, and the '70000 % 65536 == 4464' value is be written to the 'var_sum' variable.
The MISRA standard introduces the Essential type model to prevent such errors. A variable might have the following types in this model:
Use the Essential type model to reduce the number of such subtle problems. Avoid assigning composite expressions that have a narrower essential type to variables of a wider essential type or passing such expressions to a function as an argument of a wider type.
To correct the code above, use an explicit conversion to 'uint32_t':
void foo()
{
....
uint16_t var_a = 30 000;
uint16_t var_b = 40 000;
uint32_t var_sum;
var_sum = (uint32_t)var_a + var_b; /* var_sum = 70 000 */
....
};
Now the modulo 2^32 operation is performed in all cases, no matter what size the 'int' type has, and the error doesn't occur even if 'int' has the 16-bit size.
This diagnostic is classified as:
|