On Fri, Nov 17, 2023 at 4:43 PM Jonny Grant <jg@xxxxxxxx> 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