Normally, the base need not be tested, and the only interesting errno value should be ERANGE. If the base needs to be tested, it should be tested in a call that would not otherwise fail. Otherwise, it would be easy to trigger Undefined Behavior. Consider the following example: errno = 0; val = strtol("foo", &end, -42); There's no portable way to know if the call failed due to the string or the base. Cc: Matthew House <mattlloydhouse@xxxxxxxxx> Signed-off-by: Alejandro Colomar <alx@xxxxxxxxxx> --- man3/strtol.3 | 28 +++++++++++++++++++++++++--- 1 file changed, 25 insertions(+), 3 deletions(-) diff --git a/man3/strtol.3 b/man3/strtol.3 index 1f1f98216..4b30b3269 100644 --- a/man3/strtol.3 +++ b/man3/strtol.3 @@ -184,8 +184,8 @@ .SH NOTES .I errno to 0 before the call, and then determine if an error occurred by checking whether -.I errno -has a nonzero value after the call. +.I errno == ERANGE +after the call. .P According to POSIX.1, in locales other than "C" and "POSIX", @@ -206,6 +206,21 @@ .SH NOTES .BR strtoll () or to .BR strtol (). +.SH CAVEATS +If the +.I base +needs to be tested, +it should be tested in a call where the string is known to succeed. +Otherwise, it's impossible to portably differentiate the errors. +.P +.in +4n +.EX +errno = 0; +strtol("0", NULL, base); +if (errno == EINVAL) + goto unsupported_base; +.EE +.in .SH EXAMPLES The program shown below demonstrates the use of .BR strtol (). @@ -260,13 +275,20 @@ .SS Program source \& str = argv[1]; base = (argc > 2) ? atoi(argv[2]) : 0; +\& + errno = 0; /* To distinguish success/failure after call */ + strtol("0", NULL, base); + if (errno == EINVAL) { + fprintf(stderr, "The base is not supported\en"); + exit(EXIT_FAILURE); + } \& errno = 0; /* To distinguish success/failure after call */ val = strtol(str, &endptr, base); \& /* Check for various possible errors. */ \& - if (errno != 0) { + if (errno == ERANGE) { perror("strtol"); exit(EXIT_FAILURE); } -- 2.42.0
Attachment:
signature.asc
Description: PGP signature