Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
MISRA C:2012 Rule 10.8 Question
#1
The rule 10.8 states that "The value of a composite expression shall not be cast to a different essential type category or a wider essential type".

I understand that casting to a wider type will cause incompatibilities for different compilers where int have different width, but I don't understand why we cannot cast it to a different essential type category with the same or less width. 

In other words, the example

Code:
(uint32_t)(int32_t+int32_t)  /* Non-compliant */

is non-compliant, but the rationale behind this is feels unclear to me, as this code does not have inconsistency between compilers.

A possible explanation is that:
(1) despite the fact that writing like this will guarantee consistent behavior across compilers and architectures, 
(2) it easily misleads an inexperienced human programmer to interpret the computation inside the "()" to be carried out in uint32_t, which is of course not the case,
so this is banned.

I want to know whether this human readability is the rational behind the first clause of the rule. Thanks for looking into this matter in advance!
Reply
#2
The rationale is included in the guideline. The composite expression may result in loss of data by changing the range (especially if the sum results in a negative value)
Posted by and on behalf of the MISRA C Working Group
Reply
#3
(08-08-2024, 03:37 PM)misra-c Wrote: The rationale is included in the guideline. The composite expression may result in loss of data by changing the range (especially if the sum results in a negative value)

I'm still confused here. (int32_t + int32_t) will be a int32_t (regardless of integer promotions), and then we cast it to uint32_t. 
As uint32_t is as wide as int32_t, there is no information loss (besides the conversion from int to uint, of course).

If the sum is negative, then that negative int32_t will be converted to unit32_t, which is exactly what this expression intends to do, even if there is data loss (that will always be there because you convert int to uint, and will of course lose the negative part, regardless of what you convert is an composite expression or not).

The only downside of this programming style is making the human programmer think what done inside the expression is computed in uint (think that the addition is an uint addition, but it is in fact an int one), which may cause bugs if the machine's native integer is not 2's complement (i.e. 1-complement, where signed and unsigned additions, etc. are not binary compatible).

As I see it, rule 10.8 could be better stated as "The value of a composite expression shall not be cast to a wider essential type".
It seemed that conversion to an equal or narrower type in a different essential type category will not cause problems (i.e. converting (int32_t + int32_t) to uint8_t).
Reply


Forum Jump:


Users browsing this thread: 2 Guest(s)