Hi Chris, > Date: 2026-08-01 15:26:05+0100 > From: Christopher Bazley <[email protected]> > > On Sat, Aug 1, 2026 at 12:32 AM G. Branden Robinson > <[email protected]> wrote: > > WG14 has been moving away from that notion for decades now. A recent > > example is <stdbit.h>. Why not continue in that laudable direction? > > > > I think > > > > stdmem.h > > string.h > > stdstrn.h > > > > would sharply separate concerns and promote clearer reasoning among > > application developers. > > I have been reluctant to stick my oar into this argument, but the > proposal above is the best I have seen so far.
> The trouble with
> Alex's assertion that the strn... functions are not string functions
> and therefore must be memory functions is that it strikes me as a
> false dichotomy. I understand why he makes that claim, and I
> understand the damage the confusion has caused, but I do not find it
> entirely plausible given that strncat appends to a string and strncpy
> can consume one.
You and I have actually the same opinion of strn*() functions. We only
differ in the wording, and it was likely my fault for using wording that
isn't the most precise.
I've said in the past that strn*() functions are not string functions,
and as you say this is not exactly true, since indeed, strncat(3)
produces one, and strncpy(3) may consume one.
I believe I should have said --and my most recent messages are in that
line-- that strncpy(3) and strncat(3) are not _string-only_ functions.
They have arguments that are not strings, and that's what makes them
different from the rest of <string.h>. All of the str*() functions that
are not strn*() functions --thus, the str[^n]*() functions, as Branden
called them, using regex syntax-- share this in common: they handle
strings exclusively, in all their arguments (except of course, the
integer ones); that is, it is UB if a nonstring is passed, and when they
create output, that output is a string.
The following functions, all *require* strings, and *unconditionally*
produce strings (if they produce anything):
Copy
strcpy(3)
stpcpy(3)
Catenate
strcat(3)
Duplicate
strdup(3)
strdupa(3)
Compare
streq(3)
strcmp(3)
strcasecmp(3)
strcoll(3)
strverscmp(3)
Search
strlen(3)
strnul(3)
strchrnul(3)
strchr(3)
strrchr(3)
strpbrk(3)
strstr(3)
strcasestr(3)
strspn(3)
strcspn(3)
Separate
strsep(3)
strtok(3)
Others
strxfrm(3)
This is the entire set of str[^n]*() functions from <string.h>, as
documented in string(3). The rest of functions are strn*() and mem*(),
and they share something in common: they may take nonstrings and/or may
produce nonstrings.
In fact, mempcpy(3) is not really a memory function like the other
mem*() functions. mempcpy(3) is specifically useful for handling
nonstrings (and is also useful for producing strings out of those
nonstrings later). There's no clear cut in these functions, and you may
claim that mempcpy(3) belongs more in <stdstrn.h> or <string.h> than in
<memory.h>, if only for the kind of code you'd use it for.
The only clear cut is that some functions require and produce strings
exclusively, and others may not necessarily do so (even if they may
sometimes do so).
> I also understand the deep attraction of righting
> past wrongs, but it seems to me that, in this instance, the past was
> not so satisfactory either.
>
> I am skeptical that many users will include header files that did not
> exist before C2Y, but it may be worth trying. I do not think the
> proposal to restore <memory.h> would be much better: it does not exist
> on many platforms.
In the POSIX world, reality is quite different from the rest of the
world. Here, <memory.h> is almost everywhere.
> If we are going to introduce a new separation, let
> us make it a good one.
For the reasons above, even if <memory.h> didn't exist, I'd say the
3-header solution it's not ideal.
> Christopher
Have a lovely day!
Alex
--
<https://www.alejandro-colomar.es>
signature.asc
Description: PGP signature
