uint16_t
most likely has a lower integer rank than int
. It is probably an alias for unsigned short
.
If that is the case, then integral promotion will be applied to d
and a
before they are subtracted.
Integral promotion will try to convert unsigned short
to int
if int
can hold all possible values of unsigned short
. Only if that is not the case will integral promotion to unsigned int
be performed.
Therefore the subtraction is most likely done in the type int
, not uint16_t
.
The warning is then telling you that you are casting that signed int
result to an unsigned type (uint16_t
) when you initialize total
with it, which is normally not what you want to do, because unsigned types cannot store negative values that a signed type might hold.
If it is possible that the subtraction yields a negative value, then you should not be using uint16_t
at all. Instead you should manually cast the operands to a suitable signed integral type and store the result as a suitable signed integer type (i.e. int
or int32_t
):
int32_t total = static_cast<int32_t>(d)-static_cast<int32_t>(a);
or
auto total = static_cast<int32_t>(d)-static_cast<int32_t>(a);
for a bit less repetition.
If you guarantee that the subtraction doesn't yield any negative values, then you can add a static_cast
to tell the compiler that you really know what you are doing:
uint16_t total = static_cast<uint16_t>(d-a);
or
auto total = static_cast<uint16_t>(d-a);
if you don't want to repeat the type name.