I had a lovely conversation with someone about the downfalls of std::stoi
. To put it bluntly, it uses std::strtol
internally, and throws if that reports an error. According to them, though, std::strtol
shouldn't report an error for an input of "abcxyz"
, causing stoi
not to throw std::invalid_argument
.
First of all, here are two programs tested on GCC about the behaviours of these cases:
strtol
stoi
Both of them show success on "123"
and failure on "abc"
.
I looked in the standard to pull more info:
§ 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.
That sums up the behaviour of relying on strtol
. Now what about strtol
? I found this in the C11 draft:
§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.
Given the situation of passing in "abc"
, the C standard dictates that nptr
, which points to the beginning of the string, would be stored in endptr
, the pointer passed in. This seems consistent with the test. Also, 0 should be returned, as stated by this:
§7.22.1.4
If no conversion could be performed, zero is returned.
The previous reference said that no conversion would be performed, so it must return 0. These conditions now comply with the C++11 standard for stoi
throwing std::invalid_argument
.
The result of this matters to me because I don't want to go around recommending stoi
as a better alternative to other methods of string to int conversion, or using it myself as if it worked the way you'd expect, if it doesn't catch text as an invalid conversion.
So after all of this, did I go wrong somewhere? It seems to me that I have good proof of this exception being thrown. Is my proof valid, or is std::stoi
not guaranteed to throw that exception when given "abc"
?