alx-0008 - Standardize strtoi(3) and strtou(3) from NetBSD

Paul Eggert eggert at cs.ucla.edu
Thu Mar 20 00:39:33 UTC 2025


On 3/19/25 14:23, Alejandro Colomar wrote:

> I think not reporting errors or warnings on saturation needs
> justification.

I don't know what "justification" means, but if it means a comment in 
the code I'm not sure I agree. Code where saturation is ordinarily 
what's wanted shouldn't need a comment on each nontrivial line saying 
"Saturation is OK here."


> Thanks, those changes look good.  BTW, what do you think of using
> strspn(3) to simplify the c_isspace loop?

Not worth the trouble. The loop is easier to read and debug than the 
strspn call, which got some minor details wrong and fixing that would 
complicate the strspn code even further. (The loop is typically more 
efficient too, not that this matters much here.)


> However, would you mind clarifying why you don't diagnose huge values in
> the two places that you have updated?

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.

A reasonable amount of GNU code works that way.


> 	struct foo {
> 		long  val;
> 		int   err;
> 	}
> 
> 	struct foo  ret;
> 
> 	ret = f(time_t, ...);
> 	if (ret.err != 0)
> 		err(1, "f");
> 
> How do I know which variant of struct foo I need?

I don't understand the question. There's no variant here; "variant" to 
me implies something like a union.

But to fill in the details: C doesn't have a convenient notation for 
returning multiple values, you do need a struct. One convention is to 
use a struct whose tag is the same as the function. So, something like 
this in a header file somewhere:

     struct a2i { intmax_t val; ptrdiff_t len; }
     a2i (char const *str, int base);

where LEN is negative for errors, and callers look like this:

     struct a2i r = a2i(stringval, 10);
     if (r.len < 0 || stringval[r.len])
       err("a2i", stringval, r.len);

the "|| stringval[r.len]" is needed only for callers that consider 
nonnumeric suffixes to be an error.

This is simpler than the pointers and "restrict"s in the proposed API.


More information about the libbsd mailing list