Время от времени, особенно при выполнении 64-битных сборок некоторой базы кода, я замечаю, что во многих случаях возможны целочисленные переполнения.Наиболее распространенным случаем является то, что я делаю что-то вроде этого:
// Creates a QPixmap out of some block of data; this function comes from library A
QPixmap createFromData( const char *data, unsigned int len );
const std::vector<char> buf = createScreenShot();
return createFromData( &buf[0], buf.size() ); // <-- warning here in 64bit builds
Дело в том, что std::vector::size()
приятно возвращает size_t
(что составляет 8 байтов в 64-битных сборках), но функция получаетunsigned int
(что составляет всего 4 байта в 64-битных сборках).Таким образом, компилятор предупреждает правильно.
Если возможно, я пытаюсь исправить сигнатуры, чтобы в первую очередь использовать правильные типы.Однако я часто сталкиваюсь с этой проблемой при объединении функций из разных библиотек, которые я не могу изменить.К сожалению, я часто прибегаю к некоторым рассуждениям в духе «Хорошо, никто никогда не сделает снимок экрана, генерирующий более 4 ГБ данных, так зачем беспокоиться» и просто поменяю код на
return createFromData( &buf[0], static_cast<unsigned int>( buf.size() ) );
, чтобыкомпилятор отключается.Тем не менее, это чувствует себя действительно злым.Так что я подумывал о том, чтобы иметь какое-то утверждение во время выполнения, которое, по крайней мере, приводит к приятной ошибке в сборках отладки, например:
assert( buf.size() < std::numeric_limits<unsigned int>::maximum() );
Это уже немного лучше, но мне интересно: как сделатьВы имеете дело с такой проблемой, а именно: целочисленные переполнения, которые «практически» невозможны (на практике).Я предполагаю, что это означает, что они не происходят для вас, они не происходят для QA - но они взрываются перед лицом клиента.