Одним из важных факторов является то, что это усложняет логику цикла: представьте, что вы хотите выполнить итерацию по всем элементам массива, кроме последнего (что действительно происходит в реальном мире). Итак, вы пишете свою функцию:
void fun (const std::vector<int> &vec) {
for (std::size_t i = 0; i < vec.size() - 1; ++i)
do_something(vec[i]);
}
Выглядит хорошо, не так ли? Он даже компилируется чисто с очень высоким уровнем предупреждений! (Live) Итак, вы помещаете это в свой код, все тесты проходят гладко, и вы забываете об этом.
Теперь, позже, кто-то приходит и передает пустой vector
вашей функции. Теперь с целым числом со знаком вы, надеюсь, заметили предупреждение компилятора sign-compare, представили соответствующий состав и не опубликовали код с ошибками в первую очередь.
Но в вашей реализации с целым числом без знака вы выполняете перенос, и условие цикла становится i < SIZE_T_MAX
. Катастрофа, УБ и скорее всего крах!
Я хочу знать, как они приводят к ошибкам безопасности?
Это также проблема безопасности, в частности это переполнение буфера. Одним из возможных способов использования этого было бы, если бы do_something
сделал что-то, что мог бы наблюдать злоумышленник. Возможно, они смогут определить, какие входные данные вошли в do_something
, и таким образом данные, к которым злоумышленник не должен иметь доступа, будут просочены из вашей памяти. Это будет сценарий, аналогичный ошибке Heartbleed. (Спасибо храповому уроду за указание на это в комментарии а>.)
person
Baum mit Augen
schedule
22.05.2015
int
составляет 32 бита, вычисления наint
, которые переполняются должны давать значения, которые соответствуют правильным результатам по модулю 2³², но не должны вести себя как значения в пределах... - person supercat   schedule 22.05.2015int32_t x=INT32_MAX; x++; int64_t y1=x,y2=x;
компилятору не требуется присваивать одно и то же значениеy1
иy2
, но для приведенияy1
иy2
кuin32_t
потребуется присвоить одно и то же значение, т. е. (INT32_MAX + 1u) . Я ожидаю, что явная семантика проверенных целых чисел могла бы позволить некоторые очень полезные оптимизации, если бы компилятору было разрешено проводить правильные вычисления за пределами указанной точности, и ему приходилось ловить только тогда, когда точность была потеряна. Учитываяicheck32_t w,x,y,z;
, выражениеw=x+y+z;
... - person supercat   schedule 22.05.2015x+y
, и(x+y)+z
могут быть представлены вicheck32_t
, но компилятор может свободно ловить или нет на досуге, еслиx+y
не может быть представлено, ноx+y+z
было. - person supercat   schedule 22.05.2015