The standard C library function atoi
is documented in ISO 9899:2011 as:
7.22.1 Numeric conversion functions
1 The functions
atof
,atoi
,atol
, andatoll
need not affect the value of the integer expressionerrno
on an error. If the value of the result cannot be represented, the behavior is undefined....
7.22.1.2 The
atoi
,atol
, andatoll
functionsSynopsis
#include <stdlib.h> int atoi(const char *nptr); long int atol(const char *nptr); long long int atoll(const char *nptr);
Description
2 The
atoi
,atol
, andatoll
functions convert the initial portion of the string pointed to bynptr
toint
,long int
, andlong long int
representation, respectively. Except for the behavior on error, they are equivalent toatoi: (int)strtol(nptr, (char **)NULL, 10) atol: strtol(nptr, (char **)NULL, 10) atoll: strtoll(nptr, (char **)NULL, 10)
Returns
3 The
atoi
,atol
, andatoll
functions return the converted value.
What is the intended behaviour when string pointed to by nptr
cannot be parsed as an integer? The following four opinions seem to exist:
No conversion is performed and zero is returned. This is the documentation given by some references like this one.
Behaviour is like that of strtol
except that errno
might not be set. This emerges from taking “Except for the behavior on error” as a reference to §7.22.1 ¶1.
Behaviour is unspecified. This is what POSIX says:
The call atoi(str) shall be equivalent to:
(int) strtol(str, (char **)NULL, 10)
except that the handling of errors may differ. If the value cannot be represented, the behavior is undefined.
Furthermore, the section Application Usage states:
The atoi() function is subsumed by strtol() but is retained because it is used extensively in existing code. If the number is not known to be in range, strtol() should be used because atoi() is not required to perform any error checking.
Note that POSIX claims that the specification is aligned to ISO 9899:1999 (which contains the same language as ISO 9899:2011 as far as I'm concerned):
The functionality described on this reference page is aligned with the ISO C standard. Any conflict between the requirements described here and the ISO C standard is unintentional. This volume of POSIX.1-2008 defers to the ISO C standard.
According to my local POSIX committee member, this is the historical behaviour of UNIX.
Behaviour is undefined. This interpretation arises because §7.22.1.2 ¶2 never explicitly says what happens on error. Behaviour that is neither defined nor explicitly implementation defined or unspecified is undefined.
Which of these interpretations is correct? Please try to refer to authoritative documentation.
What is the intended behaviour when string pointed to by
nptr
cannot be parsed as an integer?
To be clear, this question applies to
// Case 1
value = atoi("");
value = atoi(" ");
value = atoi("wxyz");
and not the following:
// Case 2
// NULL does not point to a string
value = atoi(NULL);
// Convert the initial portion, yet has following junk
value = atoi("123xyz");
value = atoi("123 ");
And maybe/maybe not the following depending on usage of integer.
// Case 3
// Can be parsed as an _integer_, yet overflows an `int`.
value = atoi("12345678901234567890123456789012345678901234567890");
The "non-Case 2" behavior of ato*()
depends on the meaning of error in
The
atoi
,atol
, andatoll
functions convert the initial portion of the string pointed to bynptr
toint
,long int
, andlong long int
representation, respectively. Except for the behavior on error, they are equivalent toatoi: (int)strtol(nptr, (char **)NULL, 10)
...
C11dr §7.22.1.2 2
Certainly error includes case 3: "If the correct value is outside the range of representable values". strto*()
, though maybe not ato*()
, in this case does set the error number errrno
defined in <errno.h>
. Since the specification of ato*()
does not apply to this error, overflow, the result, is UB per
Undefined behavior is otherwise indicated in this International Standard by the words ‘‘undefined behavior’’ or by the omission of any explicit definition of behavior. C11dr §4 2
For case 1, the behavior of strto*()
is well defined and is not specified to affect errno
. The spec goes into detail (§7.22.1.4 4) and calls these "no conversion", not an error. So it can asserted the case 1 strto*()
behavior is not an error, but a "no conversion". Thus per ...
"If no conversion could be performed, zero is returned. C11dr §7.22.1.4 8
... atoi("")
must return 0.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With