У меня был прекрасный разговор с кем-то о падениях std::stoi
. Грубо говоря, он использует std::strtol
внутри и выдает исключение, если это сообщает об ошибке. Однако, по их мнению, std::strtol
не должен сообщать об ошибке при вводе "abcxyz"
, из-за чего stoi
не выдает std::invalid_argument
.
Прежде всего, вот две программы, протестированные на GCC, о поведении этих случаев:
стртол
стои
Оба они показывают успех на "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
throwing std::invalid_argument
.
Результат этого важен для меня, потому что я не хочу рекомендовать stoi
как лучшую альтернативу другим методам преобразования строки в целое число или использовать его сам, как если бы он работал так, как вы ожидаете, если бы он не воспринимает текст как недопустимое преобразование.
Значит, после всего этого я где-то ошибся? Мне кажется, что у меня есть хорошее доказательство того, что это исключение было выброшено. Является ли мое доказательство действительным, или std::stoi
не гарантирует, что это исключение будет выдано при задании "abc"
?