[PATCH 1/1] string: Add stpecpy(3)

Alejandro Colomar alx.manpages@gmail.com
Mon Dec 26 00:37:01 GMT 2022


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;

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/>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: OpenPGP_signature
Type: application/pgp-signature
Size: 833 bytes
Desc: OpenPGP digital signature
URL: <https://sourceware.org/pipermail/libc-alpha/attachments/20221226/20115743/attachment.sig>


More information about the Libc-alpha mailing list