Re: [PATCH 1/2] man/man3/{mem,strn}*(): SYNOPSIS, STANDARDS: Document these as provided by <memory.h>)

Alejandro Colomar <[email protected]> Sat, 1 Aug 2026 14:39:45 +0200
Newsgroups org.kernel.vger.linux-man
Message-ID <am3lZ6l3B4Y1fvFO@devuan>
--xhah5old2smyfdhl
Content-Type: text/plain; protected-headers=v1; charset=utf-8
Content-Disposition: inline
Content-Transfer-Encoding: quoted-printable
From: Alejandro Colomar <[email protected]>
To: "G. Branden Robinson" <[email protected]>
Cc: Joseph Myers <[email protected]>, [email protected], 
	Keith Bostic <[email protected]>, Mark Harris <[email protected]>, 
	Nevin Liber <[email protected]>, JeanHeyd Meneide <[email protected]>, 
	Christopher Bazley <[email protected]>, "Serge E. Hallyn" <[email protected]>, 
	Iker Pedrosa <[email protected]>, "Evgeny Grin (Karlson2k)" <[email protected]>, 
	Kees Cook <[email protected]>, [email protected], [email protected]
Subject: Re: [PATCH 1/2] man/man3/{mem,strn}*(): SYNOPSIS, STANDARDS:
 Document these as provided by <memory.h>)
Message-ID: <am3lZ6l3B4Y1fvFO@devuan>
References: <[email protected]>
 <784288e704183a4297aeaa3d13af8edab18bc1ea.1785532392.git.alx@kernel.org>
 <[email protected]>
 <20260731215122.4p4aepsbgeoibx74@illithid>
 <[email protected]>
 <am0fnb4BMRrTajqx@devuan>
 <[email protected]>
 <am0lAEb1wuCJPDk7@devuan>
 <[email protected]>
 <20260731233253.7uwgq7m7vndqf2o2@illithid>
MIME-Version: 1.0
In-Reply-To: <20260731233253.7uwgq7m7vndqf2o2@illithid>

Hi Branden,

> Date: 2026-07-31 18:32:53-0500
> From: "G. Branden Robinson" <[email protected]>
>
[...]
>=20
> Okay, well, <memory.h>'s out due to the above, and <mem.h> collides with
> old, non-standard Borland and Watcom compilers (which live on still in
> environments like FreeDOS[1]).
>=20
> So how about <stdmem.h> or <stdmemory.h> for the standard mem*
> functions?

As I said, I think it's the other way around.  <memory.h> is great,
because there's no public record of it being obsolescent.  It has only
been _implicitly_ obsolescent, but the fact that it has remained without
much attention make it a good candidate.  Just as much as it was done
with memccpy(3) in C23, except that memccpy(3) was brought back for
bogus reasons (it's as bad as strncpy(3) for the purpose it was
standardized).

<memory.h> is already available in all systems that matter, so programs
can start using it today, as opposed to <stdmem.h>, which could only be
used relied upon around 2036 --for the early adopters--.  If we didn't
have the old <memory.h> header, I'd certainly prefer <stdmem.h>, but for
these reasons, <memory.h> seems the way to go.

> > Any reasonable change there would involve a new header, say
> > <strnpad.h> for strncpy and strncat, rather than resurrecting a very
> > old one.
>=20
> I agree with that.  As my previous email noted, I think C programmers
> apply the mem* functions differently than they do str{n,}*.  I think
> it's a good idea to erect a cordon sanitaire around the ever-troublesome
> latter functions.

I strongly disagree.

And a cordon sanitaire wouldn't help.  That's the approach that n2349
took, and it was bogus.  It's not a matter of saying "these two
functions are bad".  It's a matter of learning what each function is
good for.  And all of mem*() and strn*() are good for memory handling
and nonstring handling (which can be considered a specific case of
memory handling).  Thus, all of them belong in <memory.h>.

A cordon sanitaire will continue to ignore the fact that the problem is
not in the functions themselves, but in how users think of these
functions.  I expect in 10 years from now, if we don't do anything,
people will notice the same problems in memccpy(3) that we now attribute
to strncpy(3).

Just look at all the garbage that people have written with memccpy(3)
after it was standardized in C23.  A Debian code search will suffice to
show the brain damage.  Or you can just look at n2349, the paper that
proposed it for its standardization, which already has UB in the
examples of how it can be used for copying strings.  It's all just too
ironic.

Let's make it easy to understand these functions, and avoid blaming any
functions for what really is our lack of understanding.

> > > The solution of moving both mem*() and strn*() to <memory.h> and
> > > leaving just str*() in <string.h> is a consistent one, because
> > > <string.h> then remains strictly for string APIs, and <memory.h> is
> > > for the rest of byte handling.
> >=20
> > It's inconsistent with how people have understood C ever since it was=
=20
> > standardized.
>=20
> This claim is a bit hand-wavy.  C has spent its entire lifetime being
> notoriously poorly understood.  But especially in early days, the
> compiler would spit out something anyway.  Hackers confused the
> production of a linked object file with understanding the language.
>=20
> C has single-handedly elevated "undefined behavior" into a field of
> academic study.
>=20
> > > It wouldn't be reasonable to move strn*() to <memory.h>, and then
> > > leave mem*() in <string.h>, of course.
> > >=20
> > > Similarly, it wouldn't be reasonable to [move] strncpy/cat() to
> > > <memory.h> and leave the rest of strn*() and all of mem*() in
> > > <string.h>.
> >=20
> > On the contrary, it's only the functions for null-padded fixed-width
> > buffers that are niche functions causing confusion, compared to all
> > the rest of the functions in <string.h> for which it's a very
> > well-established and well-understood location.  Some others like
> > memccpy are *obscure*, but not confusing in the same way.
>=20
> I agree with you here, but the base+bounds nature of the mem* functions
> versus the null-terminated nature of the str[^n]* functions, warrants
> separation.

+1

> 37 years ago the C Committee seemed to feel it needed to economize on
> standard header file names, so many unrelated interfaces got piled
> together into .h files that consequently lacked coherence (in the
> Yourdon/Constantine sense).

+1

> WG14 has been moving away from that notion for decades now.  A recent
> example is <stdbit.h>.  Why not continue in that laudable direction?
>=20
> I think
>=20
> stdmem.h
> string.h
> stdstrn.h
>=20
> would sharply separate concerns and promote clearer reasoning among
> application developers.

For the reasons above, <memory.h> is better.

About the third header, I originally thought that, and in alx-0097
I wrote about adding a <nonstring.h> header.  However, the more I think
about it, the more I think these are just fine in <memory.h>.  The Linux
kernel for example, renamed strncpy(3) to strtomem_pad() --and as
discussed within WG14, the _pad in that name is redundant, so it could
perfectly have been called strtomem()--.  This shows that these
functions are not as unrelated to <memory.h> as their current names
suggest.

This, combined with the fact that they are already available through
<memory.h>, makes me think that we should just put them in <memory.h>,
which would lead people to think about a binary distinction between
<string.h> for string-only, and <memory.h> for memory stuff that doesn't
handle strings.


Have a lovely day!
Alex

>=20
> Regards,
> Branden
>=20
> [1] https://www.freedos.org/books/cprogramming/part8/



--=20
<https://www.alejandro-colomar.es>

--xhah5old2smyfdhl
Content-Type: application/pgp-signature; name="signature.asc"

-----BEGIN PGP SIGNATURE-----

iQIzBAABCgAdFiEES7Jt9u9GbmlWADAi64mZXMKQwqkFAmpt6QsACgkQ64mZXMKQ
wqlnEA/9FJTklZO0c2o9NIhUN6TwT6XeViCA6+y33JuNl2bmhxzXYI4osLTkByxR
faZRtynZJS1QwmzSnMTm1fZ2/U/MQjfkCw+BVgUeyS3s8hD3AAiF2VHjrrPu/7uA
0mm77q6YHThNc/egTB0yESmuWQb2G0U5zBB4x50k72xIdNuCKzfe8+3GXXjIO20n
RzEbkFvru8WxBmZyCfWvfyF/T8pXSDvmxPLuI3zG3qEWKQcKWMMZxPdACG3InHRK
omDHCU37VbQmu89MJUCSpI6OuRhJKtnBNMxpCvcCUK9oRokfImP9aUvuFkHqhwHq
YsgIg1aNUdd6CR0CxUYZdgyLlK/oq3rrBalb3/GJ7ajAeycL+MX3d9NrD20GoHPI
d6M1Crky31o5XpUSQ++RVxh2FKeYOpgCsd+AvMpuxkPsEMfkEid1ILP7WXjh1G9V
720VvjbzIKQXej5KA41Ubp2wkSC5voPZV2ZBPEUT2+nXd8ZZup+K+YNJM1wz8NtG
18vbfM1oTGTdYmeQoi7v3ILVNjVLY0fJ25iJZYzTh9Dlhd3AABEy0uSU05MoGGzU
ih2QZX3L4qTpoFYU/GqJoJbR0WRxkNLDICV6F1kvcDtQDWpUSUqPQC0lJOCUC0dU
7zGTYMcW7fhypCYYg+GOOjyGiBnx7bTv8ESLFZtXyKtr5VXU5Oc=
=JD77
-----END PGP SIGNATURE-----

--xhah5old2smyfdhl--