From: Bruno Haible <bruno@clisp.org>
To: Alejandro Colomar <alx@kernel.org>
Cc: liba2i@lists.linux.dev, sc22wg14@open-std.org,
libbsd@lists.freedesktop.org, tech-misc@netbsd.org,
christos <christos@netbsd.org>,
"Đoàn Trần Công Danh" <congdanhqx@gmail.com>,
"Paul Eggert" <eggert@cs.ucla.edu>,
"Eli Schwartz" <eschwartz93@gmail.com>,
"Guillem Jover" <guillem@hadrons.org>,
"Iker Pedrosa" <ipedrosa@redhat.com>,
"Michael Vetter" <jubalh@iodoru.org>,
"Robert Elz" <kre@netbsd.org>,
riastradh@netbsd.org, "Sam James" <sam@gentoo.org>,
"Serge E. Hallyn" <serge@hallyn.com>
Subject: Re: alx-0008 - Standardize strtoi(3) and strtou(3) from NetBSD
Date: Tue, 18 Mar 2025 22:53:09 +0100 [thread overview]
Message-ID: <18739733.sWSEgdgrri@nimes> (raw)
In-Reply-To: <mgcfwxfmv3kpfnkkf6uj63kx5tdzl64p2zg2us4ntsu6q5xkwj@k52z5yyiywoo>
Hi Alejandro,
> Below is a draft of a proposal for standardization of strtoi/u(3) from
> NetBSD in ISO C2y.
First of all: I like your initiative, and I moderately like this proposal.
> The strtol(3) family of functions is do damn hard to use
> correctly. Only a handful of programmers in the world really
> know how to use it correctly in all the corner cases, and even
> those need to be really careful to not make mistakes.
It would be useful to list the mistakes that are being made most frequently;
so as to verify that the proposed strtoi / strtou functions don't tend
to provoke the same mistakes. (I'd guess that one of the frequent mistakes
is that when the number is not expected to occupy the entire string,
the success test after (errno = 0, strtol (...)) is
endptr > nptr && errno == 0
and programmers tend to forget one of the two conditions.)
> +Synopsis
> +1 #include <stdlib.h>
> + intmax_t strtoi(const char *restrict s, char **restrict endp, int base,
> + intmax_t min, intmax_t max, int *rstatus);
> + uintmax_t strtou(const char *restrict s, char **restrict endp, int base,
> + uintmax_t min, uintmax_t max, int *rstatus);
Probably it will be an impediment to adoption that these functions work
on [u]intmax_t, which is 64-bits or 128-bits integers, which seems overkill
when people want to parse, say, a port number in the range 0..65535.
To address this adoption problem, how about changing these function to
generic functions (in the sense of <tgmath.h>)? In such a way that
strtoi (n, &end, base, LONG_MIN, LONG_MAX, &status)
is known to return a 'long' rather than 'intmax_t', and
strtoi (n, &end, base, INT_MIN, INT_MAX, &status)
is known to return an 'int' rather than 'intmax_t'.
If the standard does NOT say that these functions are generic, it would
be harder for an implementation to optimize invocations of these
functions for narrower types: I don't see how it could be done without
explicit compiler support.
> + Instead, they set the object pointed to by <tt>rstatus</tt>
> + to an error code,
> + or to zero on success.
> +
> +12 -- EINVAL The value in <tt>base</tt> is not supported.
> + -- ECANCELED The given string did not contain
> + any characters that were converted.
> + -- ERANGE The converted value was out of range
> + and has been coerced,
> + or the range was invalid (e.g., min > max).
> + -- ENOTSUP The given string contained characters
> + that did not get converted.
> +
> +13 If various errors happen in the same call,
> + the first one listed here is reported.
It would be useful to show how a success test looks like, after
strtoi (s, &end, base, min, max, &status)
for each of the four frequent use-cases:
-a. expect to parse the initial portion of the string, no coercion,
-b. expect to parse the initial portion of the string, silent coercion,
-c. expect to parse the entire string, no coercion,
-d. expect to parse the entire string, silent coercion.
AFAICS, the success tests are:
-a. status == 0 || status == ENOTSUP
-b. status == 0 || status == ENOTSUP || status == ERANGE
-c. status == 0
-d. status == 0 || (status == ERANGE && end > s && *end == '\0')
The success test in case d. is so complicated that, for my feeling, the goal
to avoid programmer mistakes is not being met.
I would therefore propose to change the status value to a bit mask, so that
the error conditions "The converted value was out of range and has been
coerced" and "The given string contains characters that did not get converted"
can be both returned together, without conflicting.
And, while at it, the error condition "min > max" is an error that is
independent of the given string contents; I would better see it mapped to
EINVAL rather than ERANGE.
Bruno
next prev parent reply other threads:[~2025-03-18 21:54 UTC|newest]
Thread overview: 43+ messages / expand[flat|nested] mbox.gz Atom feed top
[not found] <20250318142555.09A86356820@www.open-std.org>
2025-03-18 13:54 ` alx-0008 - Standardize strtoi(3) and strtou(3) from NetBSD Alejandro Colomar
2025-03-18 21:16 ` Alejandro Colomar
2025-03-18 21:53 ` Bruno Haible [this message]
2025-03-18 22:43 ` Alejandro Colomar
2025-03-19 0:15 ` Bruno Haible
2025-03-19 15:26 ` Alejandro Colomar
2025-03-19 18:48 ` Alejandro Colomar
2025-03-19 18:56 ` Alejandro Colomar
2025-03-19 21:59 ` Bruno Haible
2025-03-19 23:12 ` Alejandro Colomar
2025-03-19 23:30 ` strtou(3) handling of negative input Alejandro Colomar
2025-03-19 23:52 ` alx-0008 - Standardize strtoi(3) and strtou(3) from NetBSD Thorsten Glaser
2025-03-20 0:19 ` Alejandro Colomar
2025-03-20 0:31 ` Thorsten Glaser
2025-03-20 0:36 ` Alejandro Colomar
2025-03-19 23:52 ` nullability of status parameter in strtoi/u(3) Alejandro Colomar
2025-03-20 12:44 ` alx-0008 - Standardize strtoi(3) and strtou(3) from NetBSD Bruno Haible
2025-03-20 12:55 ` Alejandro Colomar
2025-03-20 17:18 ` Thorsten Glaser
2025-03-20 14:26 ` Bruno Haible
2025-03-20 14:54 ` Alejandro Colomar
2025-03-19 19:27 ` Paul Eggert
2025-03-19 20:05 ` Alejandro Colomar
2025-03-19 20:39 ` Paul Eggert
2025-03-19 21:23 ` Alejandro Colomar
2025-03-20 0:39 ` Paul Eggert
2025-03-20 1:15 ` Alejandro Colomar
2025-03-20 7:03 ` Paul Eggert
2025-03-20 10:32 ` Alejandro Colomar
2025-03-19 15:56 ` Thorsten Glaser
2025-03-19 16:25 ` Alejandro Colomar
2025-03-19 16:36 ` Thorsten Glaser
2025-03-19 16:53 ` Alejandro Colomar
2025-03-19 17:35 ` Bruno Haible
2025-03-19 18:01 ` Alejandro Colomar
2025-03-20 16:13 ` alx-0008r2 " Alejandro Colomar
2025-03-18 17:20 ` [SC22WG14.29900] alx-0008 " Joseph Myers
2025-03-18 20:18 ` Alejandro Colomar
[not found] ` <20250318201854.66AB5356895@www.open-std.org>
2025-03-18 21:11 ` [SC22WG14.29912] " Joseph Myers
2025-03-18 21:35 ` Alejandro Colomar
2025-03-18 21:40 ` Alejandro Colomar
2025-03-18 22:14 ` Joseph Myers
2025-03-18 22:49 ` Alejandro Colomar
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=18739733.sWSEgdgrri@nimes \
--to=bruno@clisp.org \
--cc=alx@kernel.org \
--cc=christos@netbsd.org \
--cc=congdanhqx@gmail.com \
--cc=eggert@cs.ucla.edu \
--cc=eschwartz93@gmail.com \
--cc=guillem@hadrons.org \
--cc=ipedrosa@redhat.com \
--cc=jubalh@iodoru.org \
--cc=kre@netbsd.org \
--cc=liba2i@lists.linux.dev \
--cc=libbsd@lists.freedesktop.org \
--cc=riastradh@netbsd.org \
--cc=sam@gentoo.org \
--cc=sc22wg14@open-std.org \
--cc=serge@hallyn.com \
--cc=tech-misc@netbsd.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.