uint16_t
скорее всего имеет более низкий целочисленный ранг, чем int
. Вероятно, это псевдоним для unsigned short
.
. Если это так, то интегральное повышение будет применено к d
и a
до их вычитания.
Интегральное продвижение попытается преобразовать unsigned short
в int
, если int
может содержать все возможные значения unsigned short
. Только если это не так, будет выполнено интегральное повышение до * 1016. *.
Поэтому вычитание, скорее всего, выполняется в типе int
, а не uint16_t
.
Предупреждение затем говорит вам, что вы приводите тот результат со знаком int
к типу без знака (uint16_t
), когда вы инициализируете total
с ним, что обычно не то, что вы хотите сделать, потому что типы без знака не могут хранить отрицательные значения, которые может иметь место тип со знаком.
Если возможно , возможно, что вычитание даст отрицательное значение, тогда вам вообще не следует использовать uint16_t
. Вместо этого вы должны вручную привести операнды к подходящему целочисленному типу со знаком и сохранить результат как подходящий целочисленный тип со знаком (например, int
или int32_t
):
int32_t total = static_cast<int32_t>(d)-static_cast<int32_t>(a);
или
auto total = static_cast<int32_t>(d)-static_cast<int32_t>(a);
для чуть меньшего количества повторений.
Если вы гарантируете, что вычитание не даст никаких отрицательных значений, тогда вы можете добавить static_cast
, чтобы сообщить компилятору, что вы действительно знаете, что делаете:
uint16_t total = static_cast<uint16_t>(d-a);
или
auto total = static_cast<uint16_t>(d-a);
, если вы не хотите повторять имя типа.