To understand what has caused teh warning, you have to understand (or at least be aware) of C's somewhat arcane and sometimes surprising type promotion rules.
The C bit-wise and arithmetic operators operate on int
or unsigned int
or larger types, so when presented with operands of a a smaller type an implicit promotion occurs:
Consider this "experiment" for example:
#include <stdint.h>
#include <stdio.h>
int main()
{
uint8_t a ;
uint8_t b ;
printf( "sizeof(a) = %zu\n", sizeof(a) ) ;
printf( "sizeof(b) = %zu\n", sizeof(b) ) ;
printf( "sizeof(a | b) = %zu\n", sizeof(a | b) ) ;
printf( "sizeof((uint8_t)(a | b)) = %zu\n", sizeof((uint8_t)(a | b)) ) ;
printf( "sizeof(a >> 3) = %zu\n", sizeof(a >> 3) ) ;
printf( "sizeof((uint8_t)(a >> 3)) = %zu\n", sizeof((uint8_t)(a >> 3)) ) ;
return 0;
}
The output (where int
is 32-bit) is:
sizeof(a) = 1
sizeof(b) = 1
sizeof(a | b) = 4
sizeof((uint8_t)(a | b)) = 1
sizeof(a >> 3) = 4
sizeof((uint8_t)(a >> 3)) = 1
So in the first case:
AP_component_require_auth |= (uint8_t)apX_compY_bitmask;
The uint8_t
cast serves no purpose since it already is that type, and certainly does not defeat the implicit conversion.
I am not familiar with CERT-C or Coverity, but in similar tools I have used, an implicit cast may be used to assert that the expression is deliberate:
AP_component_require_auth = (uint_8_t)(AP_component_require_auth | apX_compY_bitmask) ;
y_loc = (uint8_t)(major_revision >> 3) ;
As you can see it is not possible to resolve this using |=
because you cannot then cast the result of the |
expression before assignment.
However often it is better to maintain type agreement and avoid either implicit or explicit conversions and use int
, unsigned
or equal/larger sized integer type if there is no compelling reason to use a smaller type.
The issue in both cases is the assignment of an int
sized type to a uint8_t
. Though the first warning is somewhat confusing - probably due to the use of |=
- preventing it form presenting the implicitly cast expression; you should get the same error without the unnecessary cast I think. The static analysis tool I am familiar with, would say something like:
implicit conversion to smaller type in assignment
in both these cases, which is I think is much clearer.
The Coverity warning is terse and minimal; if you go directly to the standard it is enforcing, it is much more explicit and gives rationale, examples and solutions: https://wiki.sei.cmu.edu/confluence/display/c/INT31-C.+Ensure+that+integer+conversions+do+not+result+in+lost+or+misinterpreted+data