I try to give my point of view, besed on what I understood.
In the first case, every constant value is first casted to uint16_t, and so the sum is the constant expression 5U. This expression fits into uint8_t type and so can be assigned to u8a (UTLR - the unsigned type having the lowest rank required to represent the value of a particular integer constant expression or the maximum value of a bit-field).
In the second case, there is a constant expression (2U + 3U) which could be assigned directly to u8a, but then there is an explicit C-cast of this expression to uint16_t.
This cast promotes the expression to the C standard type uint16_t, and this can't be assigned to u8a.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
In the first case, every constant value is first casted to uint16_t, and so the sum is the constant expression 5U.
Thanks for the explanation.. So the sum has a more narrow essential type than its operands. That is a bit weird imho. But it is a logic I can implement.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
The expression is c1 & c2. c1 and c2 are variables with type char. The essential types for c1 and c2 should be signed char shouldn't it? So 10.1 should not be reported for that?
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
I'm not 100% sure, but I think that when bitwise operations are applied to signed narrow types, they're promoted to int.
And so the misra violation comes.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
I'm not 100% sure, but I think that when bitwise operations are applied to signed narrow types, they're promoted to int.
Well according to the C standard.. both signed char and unsigned char will be promoted to int. So yes technically it will be int no matter what sign there is. I just rewrite the test for now..
I'm not sure about the question in the OP post. But here is my understanding of the example in the test suite.
The first example has a rvalue with 5U value, without explicit specification of the type. The MISRA document introduces a definition of Unsigned Type of Lowest Rank (UTLR) in Appendix D3. This roughly means the minimal possible unsigned type that can hold the given value. uint8_t can store 5U value, so there is no error.
The second example provides the explicit cast of the result to the uint16_t type. So the result value needs at least 2 bytes in memory and can't be stored in uint8_t.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
the misra check (d62242da27e0) with --std=c99 and --platform=arm32-wchar_t2 does output the misra-c2012-10.6 for the line 3. It does not output the misra-c2012-10.3 for the line 4. You would see the 10.3 be reported when instead of the number 30 above you write 300. Both are bugs:
The C standard states that the signed integer is smallest container that the literal value is to be fitted in, in this platform int32_t. But with U it is uint32_t. but clearly misra check takes it as unsigned char.
Hi all, please confirm if my understanding is correct !
Last edit: Peeter Vois 2021-10-13
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
I wonder if you have a better understanding of essential type than I?
For instance, I want to implement misra rule 10.3. I have seen some example code here:
https://gitlab.com/MISRA/MISRA-C/MISRA-C-2012/Example-Suite/-/blob/master/R_10_03.c
I feel I need to understand these examples better.
for instance:
Do you understand why the first expression is compliant (does that RHS have the essential type "unsigned char"?) and the second is not?
I try to give my point of view, besed on what I understood.
In the first case, every constant value is first casted to
uint16_t
, and so the sum is the constant expression5U
. This expression fits intouint8_t
type and so can be assigned tou8a
(UTLR - the unsigned type having the lowest rank required to represent the value of a particular integer constant expression or the maximum value of a bit-field).In the second case, there is a constant expression
(2U + 3U)
which could be assigned directly tou8a
, but then there is an explicit C-cast of this expression touint16_t
.This cast promotes the expression to the C standard type
uint16_t
, and this can't be assigned tou8a
.Thanks for the explanation.. So the sum has a more narrow essential type than its operands. That is a bit weird imho. But it is a logic I can implement.
I have a doubt about our test code.
https://github.com/danmar/cppcheck/blob/2.5/addons/test/misra/misra-test.c#L574
The expression is
c1 & c2
. c1 and c2 are variables with typechar
. The essential types forc1
andc2
should besigned char
shouldn't it? So 10.1 should not be reported for that?Well, according to git blame, this was my fix for the false negative in rule 10.1: https://trac.cppcheck.net/ticket/9489 .
This ticket contains a link to the following line in the example suite: https://gitlab.com/MISRA/MISRA-C/MISRA-C-2012/Example-Suite/blob/master/R_10_01.c#L77 . So, the test clearly implements this case.
Thanks! This is really tricky :-(
Last edit: Daniel Marjamäki 2021-07-19
I'm not 100% sure, but I think that when bitwise operations are applied to signed narrow types, they're promoted to
int
.And so the misra violation comes.
Well according to the C standard.. both
signed char
andunsigned char
will be promoted toint
. So yes technically it will beint
no matter what sign there is. I just rewrite the test for now..I have the feeling we need to review the handling of essential types in misra.py. Somebody should run through the examples here:
https://gitlab.com/MISRA/MISRA-C/MISRA-C-2012/Example-Suite/-/blob/master/
I'm not sure about the question in the OP post. But here is my understanding of the example in the test suite.
The first example has a rvalue with
5U
value, without explicit specification of the type. The MISRA document introduces a definition of Unsigned Type of Lowest Rank (UTLR) in Appendix D3. This roughly means the minimal possible unsigned type that can hold the given value.uint8_t
can store5U
value, so there is no error.The second example provides the explicit cast of the result to the
uint16_t
type. So the result value needs at least 2 bytes in memory and can't be stored inuint8_t
.I'm struggling with the misra checks on a very similar issue and found following that I would say is a bug:
the misra check (d62242da27e0) with --std=c99 and --platform=arm32-wchar_t2 does output the misra-c2012-10.6 for the line 3. It does not output the misra-c2012-10.3 for the line 4. You would see the 10.3 be reported when instead of the number 30 above you write 300. Both are bugs:
The C standard states that the signed integer is smallest container that the literal value is to be fitted in, in this platform int32_t. But with U it is uint32_t. but clearly misra check takes it as unsigned char.
Hi all, please confirm if my understanding is correct !
Last edit: Peeter Vois 2021-10-13