All of lore.kernel.org
 help / color / mirror / Atom feed
From: Alejandro Colomar <alx@kernel.org>
To: linux-man@vger.kernel.org
Cc: Keith Bostic <keith@bostic.com>,
	Joseph Myers <josmyers@redhat.com>,
	 Mark Harris <mark.hsj@gmail.com>,
	Nevin Liber <nevin@cplusplusguy.com>,
	 JeanHeyd Meneide <phdofthehouse@gmail.com>,
	Christopher Bazley <chris.bazley.wg14@gmail.com>,
	 "Serge E. Hallyn" <serge@hallyn.com>,
	Iker Pedrosa <ipedrosa@redhat.com>,
	 "Evgeny Grin (Karlson2k)" <k2k@drgrin.dev>,
	Kees Cook <keescook@chromium.org>,
	bug-gnulib@gnu.org,  libc-alpha@sourceware.org
Subject: Re: [PATCH 0/2] alx-0097r1 - <memory.h>, the legitimate header for memcpy(3) et al.
Date: Fri, 31 Jul 2026 23:20:33 +0200	[thread overview]
Message-ID: <am0RdPxvbIYUKAL-@devuan> (raw)
In-Reply-To: <cover.1785532392.git.alx@kernel.org>

[-- Attachment #1: Type: text/plain, Size: 13850 bytes --]

> Date: 2026-07-31 23:18:54+0200
> From: Alejandro Colomar <alx@kernel.org>
>
> Hi!
> 
> Here's a patch set for documenting mem*(3) and strn*(3) functions as
> provided in <memory.h>.  This should put a stop to the misunderstanding
> and misuse of these functions as handling strings; they handle bytes and
> nonstrings (and in some cases, strings can be used as nonstrings or as
> byte arrays, but very carefully).
> 
> This header is quite portable: {Free,Net,Open}BSD, glibc, and musl, at
> least and since forever.
> 
> The C Committee is discussing standardization of <memory.h>, so let's
> give it a bump.

Here's a draft of the proposal:

---
Name
	alx-0097r1 - <memory.h>, the legitimate header for memcpy(3) et al.

Principles
	-  Avoid ambiguities
	-  Codify existing practice to address evident deficiencies

Category
	Revert regression; library

Author
	Alejandro Colomar <alx@kernel.org>

	Cc: Mark Harris <mark.hsj@gmail.com>
	Cc: Nevin Liber <nevin@cplusplusguy.com>
	Cc: JeanHeyd Meneide <phdofthehouse@gmail.com>
	Cc: Joseph Myers <josmyers@redhat.com>
	Cc: Keith Bostic <keith@bostic.com>

History
	<https://www.alejandro-colomar.es/src/alx/alx/wg14/alx-0097.git/>

	r0 (2026-07-31):
	-  Initial draft.

	r1 (2026-07-31):
	-  Avoid cd(1).

Rationale
	The standard mixes functions for handling strings, functions for
	handling bytes, and other hybrids, all in a single header file:
	<string.h>.

	This has historically caused confusion, as for example leading
	to believe that strncpy(3) is appropriate to handle strings.

	Let's separate the standard clearly into three different header
	files that differentiate these APIs.

    System V
	It turns out that mem*() functions haven't been always in
	<string.h>.  These functions were first introduced in 1983 in
	System V, and were added in a separate <memory.h> file.  Very
	soon, they were added to 4.3BSD in 1986 for compatibility to
	System V, also in <memory.h>.

	Most modern-day POSIX-compatible libc implementations still
	provide this header file for backwards compatibility reasons:

		$ find ~/src/bsd/freebsd/main/ | grep /include/memory.h
		/home/alx/src/bsd/freebsd/main/include/memory.h
		$ find ~/src/bsd/netbsd/trunk/ | grep /include/memory.h
		/home/alx/src/bsd/netbsd/trunk/include/memory.h
		$ find ~/src/bsd/openbsd/master/ | grep /include/memory.h
		/home/alx/src/bsd/openbsd/master/include/memory.h
		$ find ~/src/gnu/glibc/master/ | grep /include/memory.h
		/home/alx/src/gnu/glibc/master/include/memory.h
		$ find ~/src/musl/libc/master/ | grep /include/memory.h
		/home/alx/src/musl/libc/master/include/memory.h

    C89
	It seems that it was C89 that moved the mem*() functions to
	<string.h>, even though the Rationale document for C89 doesn't
	mention it at all.

	This was a huge mistake --we can see the consequences in the
	many misuses of these functions, and programmers that believe
	they are appropriate for uses that they are unappropriate-- that
	we can undo now.

    Design decisions
	To avoid breaking the world, let's provide the declarations of
	mem*() in both <string.h> and the old-but-new <memory.h>.  This
	will allow existing programs to continue working without
	changes.  It will also allow new programs to use the more
	higienic header files.

	This is actually what is done by existing implementations, which
	provide the declarations in both header files.  So, this is
	standardization of prior art.

    <nonstring.h>
	The strn*() functions didn't have their own separate header, but
	to avoid miususe, let's have a third header file for them.
	The name comes from the GCC [[gnu::nonstring]] attribute, which
	is used to refer to things that are somewhat similar to a string
	but aren't really a string (they are not necessarily
	NUL-terminated).

	Strings are valid nonstrings, but not the other way around.
	This is why some strn*() functions still work well on strings,
	such as strncmp(3).  However, that shouldn't prevent moving them
	to this header file.

	Also, some strn*() functions work with strings in some
	parameters, while taking nonstrings in others.  For example,
	strncat(3) takes a nonstring, and produces a string; and
	strncpy(3) takes a string (or a nonstring), and produces a
	nonstring.  Let's put all of these in <nonstring.h>, so that
	<string.h> will remain as a header file for functions that
	*exclusively* handle strings.

    <wchar.h>
	Because <wchar.h> is already more packed than <string.h>,
	containing also stuff that would correspond to other headers
	(e.g., wcstol(3)), let's not split that one.  A refactor of
	<wchar.h> should entertain a much larger task, and create files
	such as <wstring.h>, <wstdlib.h>, <wmemory.h>, etc.

Proposed wording
	Based on N3886.

    7  Library
	@@ New subclause after 7.27 ("_Noreturn <stdnoreturn.h>")
	+7.<27+1>  Memory handling <memory.h>
	+7.<27+1>.1  Memory function conventions

	@@ Copy 7.28.1p1 as 7.<27+1>.1p1, then:
	 The header
	-<string.h>
	+<memory.h>
	 declares one type,
	 several functions,
	-several type-generic functions,
	+one type-generic function,
	 and defines two macros
	 useful for manipulating
	-arrays of character type and other
	 objects
	 treated as arrays of character type.
	-328)
	+AAA)
	 The type is <b>size_t</b>
	 and one of the macros is <b>NULL</b>
	 (both described in 7.22).
	 Various methods are used for
	 determining the lengths of the arrays,
	 but in all cases a
	-<b>char *</b> or
	 <b>void *</b> argument
	 points to
	 the initial (lowest addressed) character
	 of the array.
	 If an array is accessed beyond the end of an object,
	 the behavior is undefined.
	+
	+AAA)
	+	See "future library directions" (7.35.<17+1>)

	@@ p2
	+2
	+	The macro
	+		__STDC_VERSION_MEMORY_H__
	+	is an integer constant expression
	+	with a value equivalent to <tt>202ymmL</tt>.

	@@
	## Copy 7.28.1p3 as 7.<27+1>.1p3, verbatim.
	## Copy 7.28.1p4 as 7.<27+1>.1p4, verbatim.

	+7.<27+1>.2  Copying functions
	## Move 7.28.2.1 as 7.<27+1>.2.1 ("The memcpy function").
	## Move 7.28.2.2 as 7.<27+1>.2.2 ("The memccpy function").
	## Move 7.28.2.3 as 7.<27+1>.2.3 ("The memmove function").

	+7.<27+1>.3  Comparison functions
	+7.<27+1>.3.1  General
	@@ Copy 7.28.4.1p1 as 7.<27+1>.3.1p1, then:
	 The sign of a nonzero value
	 returned by the comparison functions
	 <b>memcmp</b>
	-, strcmp, and strncmp
	 is determined by the sign of
	 the difference between
	 the values of the first pair of characters
	 (both interpreted as unsigned char)
	 that differ in the objects being compared.

	@@
	## Move 7.28.4.2 as 7.<27+1>.3.2 ("The memcmp function").

	+7.<27+1>.4  Search functions
	+7.<27+1>.4.1  Introduction
	@@ Copy 7.28.5.1p1 as 7.<27+1>.4.1p1, then:
	 The stateless search functions
	 in this subclause
	 (<b>memchr</b>
	-, strchr, strpbrk, strrchr, strstr
	 )
	 are <i>generic functions</i>.
	 These functions are
	 generic
	 in the qualification of the array to be searched
	 and will return a result pointer to an element
	 with the same qualification as the passed array.
	 If the array to be searched is <b>const</b>-qualified,
	 the result pointer will be to a <b>const</b>-qualified element.
	 If the array to be searched is not <b>const</b>-qualified,
	-332)
	+BBB)
	 the result pointer will be to an unqualified element.

	## Copy footnote 332) as BBB), verbatim.

	@@ Copy 7.28.5.1p2 as 7.<27+1>.4.1p2, then:
	 The external declarations
	 of these generic functions
	 have a concrete function type
	 that returns a pointer to an unqualified element
	-(
	 of type
	-<b>char</b> when specified as <bi>QChar</bi>, and
	 <b>void</b>
	-when specified as <bi>QVoid</bi>
	-)
	 ,
	 and accepts a pointer to
	 a <b>const</b>-qualified array of the same type to search.
	 This signature supports all correct uses.
	 If the macro definition of
	 any of these generic functions
	 is suppressed to access
	 an actual function,
	 the external declaration
	 with the corresponding concrete type is visible.
	-333)
	+CCC)

	@@
	## Copy footnote 333) as CCC), verbatim.
	## Copy 7.28.5.1p3 as 7.<27+1>.4.1p3, verbatim.

	@@
	## Move 7.28.5.2 as 7.<27+1>.4.2 ("The memchr function").

	+7.<27+1>.5  Miscellaneous functions
	## Move 7.28.6.1 as 7.<27+1>.5.1 ("The memset function").
	## Move 7.28.6.2 as 7.<27+1>.5.2 ("The memset_explicit function").

    7.28  String handling <string.h>
	@@ New subsection after title
	+7.28.<0+1>  General
	+1
	+	The header <string.h>
	+	includes the headers <memory.h> and <nonstring.h>.

	@@
	## Move 7.28.1p2 as 7.28.<0+1>p2, verbatim.

    7.28.1  String function conventions
	## Delete p2 --moved elsewhere--.

    7.28.2  Copying functions
	## Delete 7.28.2.1 ("The memcpy function") --moved elsewhere--.
	## Delete 7.28.2.2 ("The memccpy function") --moved elsewhere--.
	## Delete 7.28.2.3 ("The memmove function") --moved elsewhere--.
	## Delete 7.28.2.5 ("The strncpy function") --moved elsewhere--.
	## Delete 7.28.2.7 ("The strndup function") --moved elsewhere--.

    7.28.3  Concatenation functions
	@@ Title
	-Concatenation
	+Catenation

	@@
	## Delete 7.28.3.2 ("The strncat function") --moved elsewhere--.

    7.28.4.1  Comparison functions :: General
	@@ p1
	 The sign of a nonzero value
	 returned by the comparison functions
	+(
	-memcmp,
	 strcmp
	-, and strncmp
	+)
	 is determined by the sign of the difference
	 between the values of the first pair of characters
	 (both interpreted as unsigned char)
	 that differ in the objects being compared.

    7.28.4  Comparison functions
	## Delete 7.28.4.2 ("The memcmp function") --moved elsewhere--.
	## Delete 7.28.4.5 ("The strncmp function") --moved elsewhere--.

    7.28.5.1  Search functions :: Introduction
	@@ p1
	 The stateless search functions
	 in this subclause
	 (
	-memchr,
	 <b>strchr</b>, <b>strpbrk</b>, <b>strrchr</b>, <b>strstr</b>
	 )
	 are <i>generic functions</i>.
	 These functions are
	 generic
	 in the qualification of the array to be searched
	 and will return a result pointer to an element
	 with the same qualification as the passed array.
	 If the array to be searched is <b>const</b>-qualified,
	 the result pointer will be to a <b>const</b>-qualified element.
	 If the array to be searched is not <b>const</b>-qualified,
	 332)
	 the result pointer will be to an unqualified element.

	@@ p2
	 The external declarations
	 of these generic functions
	 have a concrete function type
	 that returns a pointer to an unqualified element
	-(
	 of type <b>char</b>
	-when specified as <bi>QChar</bi>,
	-and <b>void</b>
	-when specified as <bi>QVoid</bi>
	-)
	 ,
	 and accepts a pointer to
	 a <b>const</b>-qualified array of the same type to search.
	 This signature supports all correct uses.
	 If the macro definition of
	 any of these generic functions
	 is suppressed to access
	 an actual function,
	 the external declaration
	 with the corresponding concrete type is visible.
	 333)

    7.28.5  Search functions
	## Delete 7.28.5.2 ("The memchr function") --moved elsewhere--.

    7.28.6  Miscellaneous functions
	## Delete 7.28.6.1 ("The memset function") --moved elsewhere--.
	## Delete 7.28.6.2 ("The memset_explicit function") --moved elsewhere--.
	## Delete 7.28.6.5 ("The strnlen function") --moved elsewhere--.

    7  Library
	@@ New subclause after 7.28 ("String handling <string.h>").
	+7.<28+1>  Nonstring handling <nonstring.h>
	+7.<28+1>.1  Nonstring function conventions

	@@ Copy 7.28.1p1 as 7.<28+1>.1p1, then:
	 The header
	-<string.h>
	+<nonstring.h>
	 declares one type,
	 several functions,
	-several type-generic functions,
	 and defines two macros
	 useful for manipulating
	 arrays of character type and other
	 objects
	 treated as arrays of character type.
	-328)
	+DDD)
	 The type is <b>size_t</b>
	 and one of the macros is <b>NULL</b>
	 (both described in 7.22).
	 Various methods are used for
	 determining the lengths of the arrays,
	 but in all cases a
	 <b>char *</b>
	-or <b>void *</b>
	 argument
	 points to
	 the initial (lowest addressed)
	 character
	 of the array.
	 If an array is accessed beyond the end of an object,
	 the behavior is undefined.
	+
	+DDD)
	+	See "future library directions" (7.35.<18+1>)

	@@ p2
	+2
	+	The macro
	+		__STDC_VERSION_NONSTRING_H__
	+	is an integer constant expression
	+	with a value equivalent to <tt>202ymmL</tt>.

	@@
	## Copy 7.28.1p3 as 7.<28+1>.1p3, verbatim.
	## Copy 7.28.1p4 as 7.<28+1>.1p4, verbatim.

	+7.<28+1>.2  Copying functions
	## Move 7.28.2.5 as 7.<28+1>.2.1 ("The strncpy function").
	## Move 7.28.2.7 as 7.<28+1>.2.2 ("The strndup function").

	+7.<28+1>.3  Catenation functions
	## Move 7.28.3.2 as 7.<28+1>.3.1 ("The strncat function").

	+7.<28+1>.4  Comparison functions
	+7.<28+1>.4.1  General
	@@ Copy 7.28.4.1p1 as 7.<28+1>.4.1p1, then:
	 The sign of a nonzero value
	 returned by the comparison functions
	-memcmp, strcmp, and
	+(
	 <b>strncmp</b>
	+)
	 is determined by the sign of
	 the difference between
	 the values of the first pair of characters
	 (both interpreted as unsigned char)
	 that differ in the objects being compared.

	@@
	## Move 7.28.4.5 as 7.<28+1>.4.2 ("The strncmp function").

	+7.<28+1>.5  Miscellaneous functions
	## Move 7.28.6.5 as 7.<28+1>.5.1 ("The strnlen function").

	## I've kept plurals in sections that only have one function.
	## This is because we may add functions in the future, so it's
	## better to keep the wording generic to avoid having to update
	## it needlessly.

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

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

  parent reply	other threads:[~2026-07-31 21:20 UTC|newest]

Thread overview: 32+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-07-31 21:18 [PATCH 0/2] alx-0097r1 - <memory.h>, the legitimate header for memcpy(3) et al Alejandro Colomar
2026-07-31 21:18 ` [PATCH 1/2] man/man3/{mem,strn}*(): SYNOPSIS, STANDARDS: Document these as provided by <memory.h> Alejandro Colomar
2026-07-31 21:23   ` Joseph Myers
2026-07-31 21:28     ` Alejandro Colomar
2026-07-31 21:54       ` Sam James
2026-07-31 22:18         ` Alejandro Colomar
2026-08-01  0:12           ` Alejandro Colomar
2026-07-31 21:51     ` on the irresponsibility of pursuing C language reform (was: [PATCH 1/2] man/man3/{mem,strn}*(): SYNOPSIS, STANDARDS: Document these as provided by <memory.h>) G. Branden Robinson
2026-07-31 21:59       ` on the irresponsibility of pursuing C language reform Sam James
2026-07-31 22:24         ` G. Branden Robinson
2026-07-31 23:19           ` Alejandro Colomar
2026-07-31 22:10       ` on the irresponsibility of pursuing C language reform (was: [PATCH 1/2] man/man3/{mem,strn}*(): SYNOPSIS, STANDARDS: Document these as provided by <memory.h>) Joseph Myers
2026-07-31 22:21         ` Alejandro Colomar
2026-07-31 22:28           ` [PATCH 1/2] man/man3/{mem,strn}*(): SYNOPSIS, STANDARDS: Document these as provided by <memory.h> G. Branden Robinson
2026-07-31 22:42           ` on the irresponsibility of pursuing C language reform (was: [PATCH 1/2] man/man3/{mem,strn}*(): SYNOPSIS, STANDARDS: Document these as provided by <memory.h>) Joseph Myers
2026-07-31 22:52             ` Alejandro Colomar
2026-07-31 23:11               ` Joseph Myers
2026-07-31 23:32                 ` G. Branden Robinson
2026-07-31 23:45                 ` on the irresponsibility of pursuing C language reform (was: " Alejandro Colomar
2026-07-31 23:08             ` [PATCH 1/2] man/man3/{mem,strn}*(): SYNOPSIS, STANDARDS: Document these as provided by <memory.h> G. Branden Robinson
2026-07-31 23:28               ` Joseph Myers
2026-07-31 23:57                 ` G. Branden Robinson
2026-08-01  0:06                   ` Alejandro Colomar
2026-07-31 22:05     ` Alejandro Colomar
2026-07-31 22:16       ` Joseph Myers
2026-07-31 22:33         ` Alejandro Colomar
2026-07-31 23:48     ` [PATCH 1/2] man/man3/{mem, strn}*(): " Collin Funk
2026-07-31 23:52       ` Alejandro Colomar
2026-08-01  0:01         ` Alejandro Colomar
2026-07-31 21:19 ` [PATCH 2/2] man/man*/{string.3,memory.h.3head}: Move functions to a new page memory.h(3head) Alejandro Colomar
2026-07-31 21:20 ` Alejandro Colomar [this message]
2026-08-01  0:25 ` [PATCH v2] man/man3/mem*(): SYNOPSIS: Document non-standard mem*() functions as provided by <memory.h> Alejandro Colomar

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=am0RdPxvbIYUKAL-@devuan \
    --to=alx@kernel.org \
    --cc=bug-gnulib@gnu.org \
    --cc=chris.bazley.wg14@gmail.com \
    --cc=ipedrosa@redhat.com \
    --cc=josmyers@redhat.com \
    --cc=k2k@drgrin.dev \
    --cc=keescook@chromium.org \
    --cc=keith@bostic.com \
    --cc=libc-alpha@sourceware.org \
    --cc=linux-man@vger.kernel.org \
    --cc=mark.hsj@gmail.com \
    --cc=nevin@cplusplusguy.com \
    --cc=phdofthehouse@gmail.com \
    --cc=serge@hallyn.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.