Как мы знаем, такой код будет генерировать предупреждение:Почему компиляторы не делают unsigned vs signed сравнения безопасными?
for (int i = 0; i < v.size(); ++i)
решения что-то вроде auto i = 0u;
, decltype(v.size())
или std::vector<int>::size_type
, но делает вид, что мы вынуждены иметь как подписанное и значение без знака. Компилятор автоматически добавит int
в unsigned int
(фактический тип не имеет значения). Используя явный листинг, static_cast<unsigned int>(i)
заставляет предупреждение уйти, но это плохо, потому что он сделал то же самое, что сделал компилятор, и заставил замолчать важное предупреждение!
Чем лучше решение:
if ((i < 0) || (static_cast<unsigned int>(i) < v.size()))
Вполне понятно, что С «ближе к металлу», и, как следствие, более небезопасным. Но в C++ для этого нет оправдания. Поскольку C++ и C расходятся (как они это делали в течение многих лет), сотни улучшений на C++ повысили безопасность. Я очень сомневаюсь, что такое изменение может повредить производительности.
Есть ли причина, по которой компиляторы не делают это автоматически?
N.B: Это происходит в реальном мире. См. Vulnerability Note VU#159523:
Эта уязвимость в Adobe Flash возникает из-за того, что Flash передает целое число со знаком в calloc(). Злоумышленник контролирует это целое число и может отправлять отрицательные числа. Поскольку calloc() принимает size_t, который без знака, отрицательное число преобразуется в очень большое число, которое обычно слишком велико для выделения, и в результате calloc() возвращает NULL, что приводит к существованию уязвимости.
Часто вы можете написать код, чтобы не допустить этого. Используйте итераторы, диапазоны для циклов, стандартные алгоритмы или, если вам нужно подсчитать, используйте 'size_t'. –
«Я очень сомневаюсь, что такое изменение может повредить работе» - если это приведет к появлению большего количества инструкций, это повредит производительности. Даже если выполнение этих инструкций перекрывается, кеш остается конечным. Условия были * намного хуже, когда эти правила были впервые написаны на камне. –
Re. Уязвимость: похоже, настоящая проблема заключается в том, что Flash не проверяет результат calloc? –