Какова лучшая стратегия избавления от «предупреждения C4267 о возможной потере данных»?
Я портировал некоторый старый код с win32 на win64. Не потому, что размер объекта win32 был слишком мал для наших нужд, а потому, что win64 теперь более стандартен, и мы хотим перенести все наши среды в этот формат (и мы также используем некоторые сторонние библиотеки, предлагающие лучшую производительность в 64 битах, чем в 32 битах) ,
Мы заканчиваем с тоннами;
предупреждение C4267: «аргумент»: преобразование из «size_t» в «...», возможная потеря данных
Главным образом из-за кода как:unsigned int size = v.size();
гдеv
является контейнером STL.
Я знаю, почему предупреждение имеет смысл, я знаю, почему оно выдается и как его можно исправить. Однако в этом конкретном примере мы никогда не сталкивались с случаями, когда размер контейнера превышалunsigned int
Это максимальное значение в прошлом .... поэтому не будет причин для появления этой проблемы при переносе кода в 64-битную среду.
У нас были дискуссии о том, что будет лучшей стратегией для подавления этих шумных предупреждений (они могут скрывать релевантное, которое мы пропустим), но мы не могли принять решение по соответствующей стратегии.
Итак, я задаю вопрос здесь, что будет лучшей рекомендуемой стратегией?
1. Используйтеstatic_cast
Использоватьstatic_cast
, Делатьunsigned int size = static_cast<unsigned int>(v.size());
, Мне это «не нравится», потому что мы теряем возможность 64-битного хранения огромного количества данных в контейнере. Но так как наш код никогда не достигал 32-битного предела, это кажется безопасным решением ...
2. Заменитьunsigned int
отsize_t
Это определенно сложнее, чемunsigned int size
объект в приведенном выше примере может быть передан другим функциям, сохранен как атрибут класса, а затем удаление предупреждения в одну строку может привести к сотне изменений кода ...
3. Отключить предупреждение
Скорее всего, это очень плохая идея, так как в этом случае также отключается предупреждение.uint8_t size = v.size()
что, безусловно, может привести к потере данных ....
4. Определите функцию «безопасного приведения» * и используйте ее
Что-толайк:
template <typename From, typename To> To safe_cast( const From& value )
{
//assert( value < std::numeric_limits<To>::max() && value > std::numeric_limits<To>::min() );
// Edit 19/05: test above fails in some unsigned to signed cast (int64_t to uint32_t), test below is better:
assert(value == static_cast<From>(static_cast<To>(value))); // verify we don't loose information!
// or throw....
return static_cast<To>( value );
}
5. Другие решения приветствуются ...
«Используйте решение 1 в этом случае, но 2 в этом случае» вполне может быть хорошим ответом.