Действительно ли std ::stoi безопасно использовать?

У меня был прекрасный разговор с кем-то о падениях 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 для stoithrowing std::invalid_argument.


Результат этого важен для меня, потому что я не хочу рекомендовать stoiкак лучшую альтернативу другим методам преобразования строки в целое число или использовать его сам, как если бы он работал так, как вы ожидаете, если бы он не воспринимает текст как недопустимое преобразование.

Значит, после всего этого я где-то ошибся? Мне кажется, что у меня есть хорошее доказательство того, что это исключение было выброшено. Является ли мое доказательство действительным, или std::stoiне гарантирует, что это исключение будет выдано при задании "abc"?

58
задан chris 24 July 2012 в 11:44
поделиться