Преобразование предупреждений компилятора

Мы компилируем, используя gcc с -Wconversion включен. Я получаю следующие предупреждения, когда я покидаю результат сдвига, возвращенный isBitSet функция ниже.

предупреждение: преобразование в ‘u_int16_t {aka short unsigned int}’ из ‘int’
может изменить его значение [-Wconversion]

#include <stdint.h>

using namespace std;

void convertToPos(uint16 in) {

auto isBitSet = [&in](uint8_t position) -> bool{
return (in & (1 << position));
};

uint16_t signal = 0;
signal |= isBitSet(1) << 9;  // Calibrated
signal |= isBitSet(2) << 10; // Corresponds to digital map
signal |= isBitSet(5) << 13; // DR
signal |= isBitSet(8) << 15; // 3D Fix

}

int main(int argc)
{
convertToPos(4);
return 0;
}

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

auto isBitSet = [&in](uint8_t position) -> uint16_t {
return (in & (1 << position)) ? 1u:0u;
};

0

Решение

Чтобы избежать предупреждения, вы можете сделать:

signal = uint16_t(signal | isBitSet(1u) << 9);

как operator | продвигает оператора uint16_t в int,

2

Другие решения

В этом случае оба операторы сдвига а также побитовое включение или оператор применить целочисленные акции к их операндам и с тех пор uint16_t может быть представлен ИНТ операнды повышены до ИНТ и поэтому gcc предупреждает вас, что преобразование из большего типа ИНТ в uint16_t может привести к потере.

C ++ способ справиться с этим заключается в использовании static_cast, похоже на следующие работы:

signal = signal | static_cast<uint16_t>(isBitSet(1) << 9);

похоже, что нет необходимости разыгрывать результат |хотя строго не должно отличаться << но я думаю gcc в состоянии сделать вывод, что в этом случае все в порядке. Технически это лучше:

signal = static_cast<uint16_t>( signal | isBitSet(1) << 9);

Для справки проект стандарта C ++ в 5.8 Операторы смены говорит:

Операнды должны быть целочисленного или незаданного типа перечисления и
интегральные продвижения выполняются. […]

и раздел 5.13 Побитовый оператор ИЛИ говорит:

Обычные арифметические преобразования выполняются; […]

обычные арифметические преобразования в этом случае заканчивается применение целочисленные акции.

2

Это не ошибка. Это говорит о том, что при преобразовании целого числа в целое число без знака значение изменится, если целое число будет отрицательным. Там действительно нет «исправить» для этого; вам просто нужно быть осторожным, какие значения неподписанный берет из подписанного. Я предполагаю, что вы используете unsigned, потому что он должен быть 0 и выше, поэтому, если что-нибудь, это исправит любые случайно введенные отрицательные значения.

-1
По вопросам рекламы [email protected]