Bezdepbonusu7Программирование: статьи и ответы

Вопрос

Преобразование из "xxxx" в "yyyy", возможная потеря данных, подавление?

Автор вопроса: baydaОтветов: 4

Иногда я получаю предупреждения с преобразованием из более длинного типа в меньший, например:

void f( unsigned short i ) // f - accept any numeric type
                           // smaller than std::vector<>::size_type
{}

std::vector < some_type > v;
..
f ( v.size() );

Обычно я использовал одно из следующих решений:

assert( v.size() <= std::numeric_limits< unsigned short >::max() );
f( static_cast< unsigned short >( v.size() ) );

or

f( boost::numeric_cast<  unsigned short >( v.size() ) );

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

Какие другие безопасные способы подавления этого предупреждения вы знаете?
Есть ли подводные камни в описанных способах?

PS: Не всегда возможно изменить подпись f, также иногда действительно следует принимать мелкий числовой тип.

ОТРЕДАКТИРОВАНО: я хочу сделать конверсию максимально безопасной.

  • Какова сигнатура функции f? Как только мы это узнаем, мы можем начать думать о том, почему вы получаете предупреждение и что мы можем с этим сделать. Michael Kristofik 04.04.2009
  • что не так со static_cast? jalf 04.04.2009
  • @jalf: ничего, но я хочу сделать конвертацию максимально безопасной. @Kristo: вопрос отредактирован. bayda 04.04.2009
  • Тогда вы можете добавить эту информацию к своему вопросу. Ваш вопрос только спрашивает, как подавить предупреждение. Но в этом случае я предлагаю посмотреть, сможете ли вы скопировать код boost::numeric_cast. Создайте свой собственный, который делает то же самое, так как это именно то, что вам нужно. jalf 04.04.2009
  • Почему утверждения больше не разрешены? Потому что слишком многие из них срабатывают во время выполнения кода? Если да, то компания стреляет в мессенджер, а код менее безопасен, чем раньше. Jonathan Leffler 04.04.2009
  • утверждения за последний месяц запрещены. - Веселый! У вашего босса остроконечные волосы? shoosh 04.04.2009

c++typessuppress-warnings

Ответы

Ответ 1 · рейтинг 7 · dirkgently

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

Ответ 2 · рейтинг 3 · JaredPar

Единственный безопасный способ справиться с этим - убедиться, что у вас нет потери конверсии во время выполнения. Код утверждения будет работать только во время отладочных сборок и допускает потерю конверсии в розничных сборках. Потери при преобразовании плохи, потому что они будут передавать совершенно неправильный размер вектора.

Что вам действительно нужно, так это механизм, предотвращающий потерю данных. Я рекомендую использовать такой класс, как SafeInt. Это предотвратит преобразование, которое переполняется или недополняется посредством создания исключения.

SafeInt<size_t> size = v.size();
f((unsigned short)size);  // Throws if size can't fit in an unsigned short

SafeInt: http://www.codeplex.com/SafeInt

Ответ 3 · рейтинг 2 · Community

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

Кстати, вы проголосовали за это в последний раз, когда я опубликовал это!

Ответ 4 · рейтинг 2 · Jens Luedicke

Поскольку size() обычно возвращает целое число без знака, должно быть вполне безопасно приводить его к типу со знаком.

f(static_cast<expected-type>(v.size()));

В противном случае измените сигнатуру функции, если это возможно.

Перевод вопроса и ответов сообщества Stack Overflow, лицензия CC BY-SA. Оригинал на Stack Overflow.

Похожие материалы