Разрешение предупреждения о преобразовании в составном назначении

В моем коде у меня много variable <<= 1; где variable имеет тип uint16_t. Компилятор выскакивает предупреждением.

преобразование в ‘uint16_t’ из ‘int’ может изменить его значение [-Wconversion]

Как я могу это решить? Я мог бы использовать длинную форму, такую ​​как variable = (uint16_t)(variable << 1) но я хотел бы сохранить короткую нотацию.

Основываясь на моем чтении стандарта, вы не можете уйти от этого предупреждения по этой причине:

 uint16_t foo; foo <<= 1; 

эквивалентно

 uint16_t foo; foo = foo << 1; 

Однако это уловлено в мире «целостного продвижения».

Значение выражения « foo << 1 » имеет тип « foo », однако перед тем, как левый сдвиг может быть проведен, он сначала должен пройти «целую рекламу»; раздел 6.3.1.1.2 стандарта C99 указывает: «если int может представлять все значения исходного типа, значение преобразуется в int».

Это делает неявную версию вашего кода (с дополнительными скобками) следующим образом:

 uint16_t foo; foo = ((int)foo) << 1; 

Учитывая, что вы находитесь в системе с 32 или 64-битными ints (или чем-то большим, чем 16, действительно), вы действительно ставите большее значение в меньшую.

Один из способов этого - четко указать ваши броски следующим образом:

 uint16_t foo; foo = (uint16_t)(foo << 1); 

Но это означает, что нет, вы не можете использовать более короткий оператор присваивания побитового сдвига.

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

 void LS(uint16_t &value, int shift) { // LS means LeftShift *value = (uint16_t)(*value << shift); } LS(&foo, 1); 

TL; DR: Нет, вы не можете использовать короткий оператор и одновременно избегать этого предупреждения.

Вы получаете предупреждение, потому что variable <<= 1; эквивалентно:

 variable = variable << 1; 

где правая сторона имеет тип int , а не uint16_t , из-за целочисленных рекламных акций по умолчанию. Лучше всего это не использовать типы меньшего размера.