[PATCH 1/1] string: Add stpecpy(3)
Noah Goldstein
goldstein.w.n@gmail.com
Mon Dec 26 02:43:40 GMT 2022
On Sun, Dec 25, 2022 at 4:37 PM Alejandro Colomar
<alx.manpages@gmail.com> wrote:
>
> On 12/26/22 01:32, Noah Goldstein wrote:
> >>> You could probably optimize out one of the branches along the line of:
> >>> if((dst - 1UL) >= (end - 1UL)) {
> >>> // if dst == NULL, then dst - 1UL -> SIZE_MAX and must be >= any value.
> >>
> >> You would need a cast, wouldn't you? Otherwise, you'll get pointer arithmetic.
> >> Pointer arithmetic with NULL is UB.
> >>
> >>> // if dst == end, then (dst - 1UL) >= (end - 1UL) will be true.
> >>> return NULL;
> >>
> >> Returning NULL on truncation would be a possibility, but then we'd need to use
> >> errno to tell the user if the error was truncation or an input NULL (which
> >> reports an error to a previous vsnprintf(3) call wrapped by [v]stpeprintf().
> >
> > I'm not sure I see what you mean. Your current logic is:
> > ```
> > if (dst == end)
> > return NULL;
> > if (dst == NULL)
> > return NULL;
>
> No; current code is:
>
> if (dst == end)
> return end;
> if (dst == NULL)
> return NULL;
I see. The code you commented earlier was NULL for both.
Either way you can just make it:
```
if((dst - 1UL) >= (end - 1UL)) {
return dst; // either dst == NULL or dst == end.
}
```
>
> NULL is an error (contents of string are undefined; per vsnprintf(3)'s spec),
> while 'end' is just truncation, and contents if the string are well defined.
>
>
> > ```
> > Equivalent (since dst >= end || dst == NULL is required) is:
> > ```
> > if((dst - 1UL) >= (end - 1UL)) {
> > return NULL;
> > }
> > ```
> > May need to be cast to a `uintptr` or something but don't see
> > what you mean about needing to check errno and such.
> >
> >>
> >> Using errno would probably counter any optimization, since you'd still need one
> >> more branch for setting errno, so I guess it's simpler to just use end for
> >> truncation.
> >>
> >>
> >> Oooor, if we reimplement __vsnprintf_internal(3) to work on size_t and never
> >> fail, then we could add a [v]stpeprintf(3) that never fails, and then this
> >> function would only bail out on truncation.
> >>
> >> Would it be possible to make __vsnprintf_internal() never fail? What are the
> >> current failing conditions; only a size greater than INT_MAX, or are there more
> >> errors?
> >
> > Don't think its worth reimplementing __vsnprintf_internal to save a single
> > branch here.
>
> It wouldn't be only for that, but also allowing to write size_t bytes of
> formatted output. However, I question how useful that is, since you only need
> that many bytes when you're catenating strings with %s, for which stpecpy(3) can
> be used; so yes, probably it's not worth it.
>
> --
> <http://www.alejandro-colomar.es/>
More information about the Libc-alpha
mailing list