5

Implicitly widening the type of a function argument or a return expression is disallowed by MISRA-C:2004 Rule 10.1, as illustrated in the following code snippet:

void foo1(int16_t x);

int16_t foo2(void) 
{
    int8_t s8a;
    ...
    foo1(s8a);                               /* not compliant */
    ...
    return s8a;                              /* not compliant */
}

But, in my understanding, they're no different than the assigning situation:

s16a = s8a;                                  /* compliant     */

What's the point? Thanks.

dingcurie
  • 121
  • 6
  • Rust has a similar restriction, where you need an explicit cast (e.g. `let a: u16 = 3u8 as u16`). There are a hand ful of dicussions about this, e.g. https://internals.rust-lang.org/t/implicit-widening-polymorphic-indexing-and-similar-ideas/1141 . I haven't read this in whole, but the summarization is, that you don't unwittingly add different types together, e.g. a u16 and a u8, because the outcome may be surprising. – hellow Oct 18 '18 at 09:03
  • I guess it's Misra-C:2004 rule 10.1`The value of an expression of integer type shall not be implicitly converted to a different underlying type if: [..] the expression is not constant and is a function argument [...]` . But below is written that they mean to disallow conversion from wider to narrower types, nothing is about the other way round. – KamilCuk Oct 18 '18 at 09:33
  • Could you please cite which MISRA C Rule you are referring to, @dingcure ? – Andrew Oct 30 '18 at 05:09
  • 1
    @Andrew As pointed out by Kamil Cuk, it's MISRA-C:2004 Rule 10.1. – dingcurie Oct 30 '18 at 09:18

1 Answers1

1

MISRA-C:2004 Rule 10.1 (the cited Guideline) states:

The value of an expression of integer type shall not be implicitly converted to a different underlying type if:

  1. it is not a conversion to a wider integer type of the same signedness, or
  2. ...

In the example cited, the conversion is to a wider integer type (int8_t to int16_t) so Rule 10.1 does not apply.

The expansion (of 10.1 and 10.2) explain that the purpose of the Rule is to prevent implicit conversions from wider to narrower types. There is no restriction the other way!

-- edit to add --

As an update, MISRA-C:2004 Rule 10.1 is spread across several Rules in MISRA C:2012... the mapping table (Addendum 1) includes the comment:

Relaxed to permit implicit widening conversions on function arguments or return values.

Therefore, for MISRA C:2012 this is no longer a violation. You may wish to consider this, if deviating the 2004 Rule (which would be, IMHO, the correct approach).

Andrew
  • 2,046
  • 1
  • 24
  • 37
  • 1
    But the OP's examples are taken from rule 10.1 (although incorrectly copied in one case). I answered the same as you, but the problem turns out to be "d) the expression is not constant and is a return expression". Why MISRA-C:2004 had this odd rule, I could not answer - as it doesn't make the slightest sense. Return values and parameters passed are lvalue conversions. A lvalue conversion to a wider integer type of the same signedness is perfectly safe. MISRA-C:2012 fortunately doesn't have this odd rule. I don't know what the committee was thinking back in 2004, regarding 10.1 c) and d). – Lundin Oct 31 '18 at 14:46
  • That is, the text "not compliant" does not come from a broken tool but from the example below MISRA-C:2004 rule 10.1. – Lundin Oct 31 '18 at 14:50
  • Answer updated. – Andrew Jan 14 '22 at 15:21