on the irresponsibility of pursuing C language reform
Paul Eggert
eggert@cs.ucla.edu
Mon Aug 3 03:28:00 GMT 2026
On 8/2/26 15:31, Alejandro Colomar wrote:
> strncat(3) is for example useful for
> implementing strndupa(3), which is quite useful (just like strndup(3))
> if you use substrings or other fixed-width arrays.
>
> #define strndupa(s, n) strncat(strcpy(alloca(n + 1), ""), s, n)
That's a bad implementation of strndupa for several reasons. (Some
reasons are: it evaluates n multiple times, it overallocates stack space
when strnlen (s, n) < n, it obviously has undefined behavior when n ==
SIZE_MAX, and it less obviously has undefined behavior because it uses
alloca as the argument of a function call.) Fixing its problems makes it
obvious that strndupa should not be implemented via strncat; it's much
saner to use memcpy. Which is why glibc does it that way.
This example is not only not a good argument *for* strncat: it is an
argument *against* strncat. It's yet another example of how strncat
almost invariably encourages bad code.
As for the glibc manual's wording in this area, I readily concede that
the the wording should be toned down (calling programmers "lazy" is just
counterproductive), but its technical aspects are pretty much on target.
Although one might valiantly argue that strncat etc. are about
substrings, that's not their original design, that's not what they're
good at, and that's not what they're mostly used for. What they're
designed for, and what they're good at, and what they're mostly used for
is arbitrary truncation of strings and string-like data, something that
goes against the GNU programming guidelines, and something that
programmers should be warned against.
We've already wasted too much of our valuable time on this topic so I'll
let you have the last word.
More information about the Libc-alpha
mailing list