По рекомендации пользователя с высоким разрешением SO, я недавно начал компиляцию с флагом -Wconversion
на моей кодовой базе. Это вызвало немало предупреждений, некоторые из которых являются законными (например, без необходимости добавлять типы signed
и unsigned
), но также некоторые головные скребки, показанные ниже:
#include <cstdint>
int main()
{
uint16_t a = 4;
uint16_t b = 5;
b += a;
return 0;
}
Когда я компилирую с g++ -Wconversion -std=c++11 -O0 myFile.cpp
, я получаю
warning: conversion to 'uint16_t {aka short unsigned int}' from 'int' may alter its value [-Wconversion]
b += a;
^
Я просмотрел некоторые аналогичные вопросы о SO (имея дело с операторами |
и <<
), посмотрел здесь и прочитал Numeric Promotions и Numeric Conversions здесь. Мое понимание состоит в том, что для выполнения математики a
и b
продвигаются до int
(так как это первый тип, который может соответствовать целому диапазону значений uint16_t
), выполняется математика, результат записывается назад... кроме результата математики есть int
, и запись, возвращаемая на uint16_t
, генерирует предупреждение. Консенсус по другим вопросам заключался в основном в том, чтобы отбросить предупреждение, и единственный способ, которым я понял, как это сделать, - b = (uint16_t)(b + a);
(или эквивалент b = static_cast<uint16_t>(b + a);
).
Не хочу, чтобы этот вопрос становился слишком широким, но предполагая, что мое понимание целочисленных рекламных акций является правильным...
- Какой лучший способ справиться с этим? Должен ли я избегать выполнения математики по типам, более узким, чем
int
? Мне кажется довольно странным, что я должен привести арифметический результат, который является тем же типом, что и все операнды (предположим, я ожидаю, что компилятор узнает об этом и подавит предупреждение). Исторически я любил использовать не больше бит, чем мне нужно, и просто дайте компилятору обработать рекламные акции/конверсии/дополнения по мере необходимости. - Кто-нибудь часто использует флаг
-Wconversion
? Уже через пару дней, используя его самостоятельно, я начинаю думать, что его лучший вариант использования - включить его, посмотреть, на что он жалуется, исправить законные жалобы, а затем отменить его. Или, возможно, мое определение "законной жалобы" нуждается в корректировке. Замена всех моих операторов+=
с помощью произнесенных бросков кажется чем-то неприятным.
У меня возникает соблазн отметить это как c
, так как эквивалентный код c
, скомпилированный с помощью gcc -Wconversion -std=c11 -O0 myFile.c
, выдает то же предупреждение. Но как есть, я использую g++
версию 5.3.1 в поле x86_64 Fedora 23. Пожалуйста, укажите мне обману, если я пропустил это; если единственный ответ/совет - отбросить предупреждение, то это обман.