Действительно ли std :: stoi безопасно использовать?
У меня был прекрасный разговор с кем-то о паденияхstd::stoi
, Проще говоря, он используетstd::strtol
внутренне, и бросает, если это сообщает об ошибке. По их словам, однако,std::strtol
не должен сообщать об ошибке для ввода"abcxyz"
, вызываяstoi
не бросатьstd::invalid_argument
.
Прежде всего, вот две программы, протестированные на GCC о поведении этих случаев:
strtol
стои
Оба они показывают успех на"123"
и провал на"abc"
.
Я посмотрел в стандарте, чтобы получить больше информации:
§ 21.5
Throws: invalid_argument if strtol, strtoul, strtoll, or strtoull reports that
no conversion could be performed. Throws out_of_range if the converted value is
outside the range of representable values for the return type.
Это подводит итог поведения полагаться наstrtol
, Теперь насчетstrtol
? Я нашел это в проекте C11:
§7.22.1.4
If the subject sequence is empty or does not have the expected form, no
conversion is performed; the value of nptr is stored in the object
pointed to by endptr, provided that endptr is not a null pointer.
Учитывая ситуацию прохождения в"abc"
стандарт C диктует, чтоnptr
, который указывает на начало строки, будет храниться вendptr
, указатель передан. Это похоже на тест. Кроме того, 0 должно быть возвращено, как указано в этом:
§7.22.1.4
If no conversion could be performed, zero is returned.
В предыдущей ссылке говорилось, что преобразование не будет выполняться, поэтому оно должно возвращать 0. Эти условия теперь соответствуют стандарту C ++ 11 дляstoi
бросаниеstd::invalid_argument
.
Результат этого важен для меня, потому что я не хочу рекомендоватьstoi
в качестве лучшей альтернативы другим методам преобразования строки в int или использования его самостоятельно, как если бы он работал так, как вы ожидаете, если он не распознает текст как недопустимое преобразование.
Итак, после всего этого я где-то ошибся? Мне кажется, у меня есть хорошее доказательство того, что это исключение было брошено. Является ли мое доказательство действительным, илиstd::stoi
не гарантируется выбросить это исключение, если"abc"
?