Re: Signing all patches and email to this list

Matthew House
2023-11-18T00:25:38Z

On Fri, Nov 17, 2023 at 4:43 PM Jonny Grant <jg@jguk.org> wrote:
> On 12/11/2023 11:26, Alejandro Colomar wrote:
> > The compiler will sometimes optimize them to normal *cpy(3) functions,
> > since the length of dst is usually known, if the previous *cpy(3) is
> > visible to the compiler. And they provide for cleaner code. If you
> > know that they'll get optimized, you could use them.
>
> May I ask, is there an example or document that shows this optimization by the compiler? Perhaps a godbolt link?
>
> So it's a strcat() optimized to a strcpy()?
>
> I know gcc might unroll and just include the values of the string bytes.
>
> Kind regards, Jonny

See <https://godbolt.org/z/e34fWrTGf>. If a function computes the strlen()
of the destination before calling strcat(), without modifying its value
between the two calls, GCC will replace the strcat() with a strcpy(). If a
function computes the strlen() of both the source and the destination, GCC
will further replace the strcat() with a memcpy(), and possibly inline the
memcpy() if the size is short enough. It will also remember the increased
length of the destination for any future strcat() calls, to accomodate for
strcpy(), strcat(), strcat(), ... chains. This is implemented in the
strlen_pass::handle_builtin_strcat() function in gcc/tree-ssa-strlen.cc.
Neither Clang nor MSVC appears to implement any similar optimization.

Nevertheless, I would be extremely wary of recommending the bare strcpy(3),
strcat(3), and sprintf(3) functions on the basis of "providing for cleaner
code". By permitting the programmer to perform the copy with no immediate
knowledge of the source and destination sizes, the functions open up a
unique opportunity for squirreling away the guaranteed sizes in distant and
opaque parts of the codebase. And this antipattern isn't a rare exception,
but shows up in nearly every library that makes extensive use of the
functions.

Thank you,
Matthew House