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. --