tech-misc archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
Re: alx-0008 - Standardize strtoi(3) and strtou(3) from NetBSD
On 2025-03-19 18:15, Alejandro Colomar wrote:
I think that you'd
benefit from range checks, actually. (See my response to his email.)
<https://lore.kernel.org/liba2i/6oyljvsenypqnrmgjbcwskqpdsag677h2dzay6hvfoosju4224@3j7iczm4d7nw/T/#m38066e6eec63a8906e3cbfea275c9d7940d8df98>
That's a long email and I'm not sure I'm looking at the right place in
it, but if I understand correctly it says that Gnulib code like this:
port = strtoul (servname, &c, 10);
if (port > 0xffff)
return EAI_NONAME;
would be clearer if worded this way:
port = strtou (servname, &c, 10, 0, 0xffff, &err);
if (err == ERANGE)
return EAI_NONAME;
If so, I disagree. The strtou API is more complicated, and the reader is
likely to forget what each of its arguments means, e.g., that the 0 is a
minimum and the 0xffff is a maximum. The strtoul API is simpler and it's
more obvious what is intended.
Do you mean that the implementation of strspn(3) was temporarily broken?
Or that the specification is bad?
No, strspn itself is fine. It's that call to strspn that is broken. The
call assumes that only ' ', '\t', and '\n' satisfy c_isspace, which is
incorrect. This is an area where c_isspace is simpler and easier to
follow than strspn.
For this particular resource, a limit of ULONG_MAX has the same practical
effect as a limit of ULONG_MAX + 1. Since the user can't tell the difference
in behavior, it's fine to implement the larger limit as the smaller one,
with no diagnostic.
According to Bruno, that limit is later clamped at a much lower value,
so I think that clamping could be moved up to the strtou(3) call.
Yes, it could be moved into strtou, but there's a cost in simplicity and
easy of understanding.
How do you get a uintmax_t?
With a different function a2u that comes with a different struct (just
like strtoi/strtou).
Also, how do I perform range checks in that call? I need to specify
min and max limits.
The caller should do the range checks, as this makes C code easier to
follow, both by the human programmer and the compiler, which can more
easily use the range information to generate better code.
For cases like these having a function do the range checks is often a
mistake - it doesn't significantly increase reliability (on the
contrary, it can reduce it). But if you prefer a function with range
checks, it's easy to add bounds arguments.
How do you know how much has been parsed on error?
Good point. I guess we'll need three elements to the structure, then.
At this point we're bikeshedding but you can have the last word if you like.
Home |
Main Index |
Thread Index |
Old Index