Hi Chris, > Date: 2026-08-01 15:26:05+0100 > From: Christopher Bazley > > On Sat, Aug 1, 2026 at 12:32 AM G. Branden Robinson > wrote: > > WG14 has been moving away from that notion for decades now. A recent > > example is . 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 . 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 , 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 or than in , 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 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, 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 didn't exist, I'd say the 3-header solution it's not ideal. > Christopher Have a lovely day! Alex --