GCC - предупреждение о преобразовании для 16-битного сложения - PullRequest
0 голосов
/ 04 июля 2018

Каким будет правильный способ разрешения предупреждений такого рода в существующей кодовой базе?

void test(uint16_t x, uint16_t y)
{
    // warning: conversion to 'uint16_t' from 'int' may alter its value
    uint16_t value = (x + 1) * y;
    ...
}

Все три значения являются 16-разрядными целыми числами без знака, и любые арифметические переполнения будут выполняться правильно без предупреждений, если int этой платформы был 16-разрядным, и я не вижу другого способа написания этого фрагмента кода, кроме от приведения результата в результате целочисленного продвижения.

  1. Должен ли я кастовать во всех таких случаях? Кастинг чувствует, что я делаю что-то не так.
  2. Отключение предупреждения? Я бы предпочел не отключать предупреждение полностью, так как это может быть полезно в некоторых случаях.

Ответы [ 2 ]

0 голосов
/ 04 июля 2018

Примечание: следующее верно только для 16-битного целого числа

предупреждение: речь шла о неявном преобразовании x в int, поскольку 1 имеет тип int. Более позднее преобразование y в int по той же причине также может вызвать это.

Просто пометьте 1 без знака

void test(uint16_t x, uint16_t y)
{
    uint16_t value = (x + 1u) * y;
    ...
}

Не требуется литье.

Это также будет работать в 16-битном случае :

void test(uint16_t x, uint16_t y)
{
    uint16_t value = x * y + y;
    ...
}
0 голосов
/ 04 июля 2018

Должен ли я разыгрывать во всех таких случаях? Кастинг чувствует, что я делаю что-то не так.

Это правильная вещь, по крайней мере, если код должен быть переносимым. Если он когда-либо компилируется только для 16-битных платформ, не должно быть предупреждения, в противном случае отключите предупреждение с явным приведением к uint16_t:

uint16_t value = (uint16_t) (x + 1) * y;

Нет ничего лучше, что вы можете сделать: все арифметические операции выполняются как (по крайней мере) int, и компилятор напоминает вам об этом. В зависимости от значений x и y вполне возможно, что результат не помещается в uint16_t. Явно записывая приведенные документы, вы знаете об этом и либо хотите усечение, либо заверяете, что этого не произойдет.

...