alx-0097r1 - <memory.h>, the legitimate header for memcpy(3) et al.
Alejandro Colomar
maintainercover alx-0097r1 - <memory.h>, the legitimate header for memcpy(3) et al.
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.
Have a lovely night!
Alex
Alejandro Colomar (2):
man/man3/{mem,strn}*(): SYNOPSIS, STANDARDS: Document these as
provided by <memory.h>
man/man*/{string.3,memory.h.3head}: Move functions to a new page
memory.h(3head)
man/man3/memccpy.3 | 5 ++- man/man3/memchr.3 | 5 ++- man/man3/memcmp.3 | 5 ++- man/man3/memcpy.3 | 5 ++- man/man3/memfrob.3 | 2 +- man/man3/memmem.3 | 2 +- man/man3/memmove.3 | 5 ++- man/man3/mempcpy.3 | 2 +- man/man3/memrchr.3 | 2 +- man/man3/memset.3 | 5 ++- man/man3/stpncpy.3 | 8 +++- man/man3/strcasecmp.3 | 6 +++ man/man3/strcmp.3 | 6 +++ man/man3/strdup.3 | 5 +++ man/man3/strdupa.3 | 4 ++ man/man3/string.3 | 95 +++-------------------------------------- man/man3/strncat.3 | 5 ++- man/man3/strnlen.3 | 5 ++- man/man3head/memory.h.3 | 57 +++++++++++++++++++++++++ 19 files changed, 126 insertions(+), 103 deletions(-) create mode 100644 man/man3head/memory.h.3
Range-diff:
-: ------------ > 1: 784288e70418 man/man3/{mem,strn}*(): SYNOPSIS, STANDARDS: Document these as provided by <memory.h>
-: ------------ > 2: 668ab8c64821 man/man*/{string.3,memory.h.3head}: Move functions to a new page memory.h(3head)base-commit: 8152eb52d9a92f02c14e843545acec7ee1946479
Signature · 1 line
2.53.0
Alejandro Colomar
maintainerPATCH 1/2 man/man3/{mem,strn}*(): SYNOPSIS, STANDARDS: Document these as provided by <memory.h>
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, for example leading to believe that strncpy(3) is appropriate to handle strings.
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
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 for which they are unappropriate-- that we can undo now.
Let's document these as provided by <memory.h>, which is still true; all POSIX-ish libc implementations I've consulted provide the <memory.h> header with mem*() functions, except two: Illumos gate, and gnulib. Let's ignore them, or rather, hope they will follow suit eventually.
This will signal to programmers that this is the header file they should be using. The C Committee is discussing the possibility of standardizing the good old <memory.h> header file, so let's give it a little bump.
Let's also move the strn*() functions there, since modern libc implementations also provide them there. And they certainly don't belong in <string.h>, so <memory.h> is more adequate.
After this change, <string.h> contains only functions that exclusively handle (and require) strings.
--- man/man3/memccpy.3 | 5 ++++- man/man3/memchr.3 | 5 ++++- man/man3/memcmp.3 | 5 ++++- man/man3/memcpy.3 | 5 ++++- man/man3/memfrob.3 | 2 +- man/man3/memmem.3 | 2 +- man/man3/memmove.3 | 5 ++++- man/man3/mempcpy.3 | 2 +- man/man3/memrchr.3 | 2 +- man/man3/memset.3 | 5 ++++- man/man3/stpncpy.3 | 8 +++++++- man/man3/strcasecmp.3 | 6 ++++++ man/man3/strcmp.3 | 6 ++++++ man/man3/strdup.3 | 5 +++++ man/man3/strdupa.3 | 4 ++++ man/man3/strncat.3 | 5 ++++- man/man3/strnlen.3 | 5 ++++- 17 files changed, 64 insertions(+), 13 deletions(-)
man/man3/memccpy.3 +4 -1
@@ -12,7 +12,7 @@ .SH LIBRARY .RI ( libc ,\~ \-lc ) .SH SYNOPSIS .nf -.B #include <string.h> +.BR #include\~<memory.h> " // See STANDARDS" .P .BR "void *memccpy(" "size_t n;" .BI " void " dest "[restrict " n "], const void " src "[restrict " n ],
@@ -67,6 +67,9 @@ .SH ATTRIBUTES .TE .SH STANDARDS POSIX.1-2008. +.P +ISO C and POSIX declare this function in +.IR <string.h> . .SH HISTORY POSIX.1-2001, SVr4, 4.3BSD. .SH SEE ALSO
man/man3/memchr.3 +4 -1
@@ -12,7 +12,7 @@ .SH LIBRARY .RI ( libc ,\~ \-lc ) .SH SYNOPSIS .nf -.B #include <string.h> +.BR #include\~<memory.h> " // See STANDARDS" .P .BR "void *memchr(" "size_t n;" .BI " const void " s [ n "], int " c ", size_t " n );
@@ -53,6 +53,9 @@ .SH ATTRIBUTES .TE .SH STANDARDS C11, POSIX.1-2008. +.P +ISO C and POSIX declare this function in +.IR <string.h> . .SH HISTORY POSIX.1-2001, C89, SVr4, 4.3BSD. .SH SEE ALSO
man/man3/memcmp.3 +4 -1
@@ -12,7 +12,7 @@ .SH LIBRARY .RI ( libc ,\~ \-lc ) .SH SYNOPSIS .nf -.B #include <string.h> +.BR #include\~<memory.h> " // See STANDARDS" .P .BR "int memcmp(" "size_t n;" .BI " const void " s1 [ n "], const void " s2 [ n "], size_t " n );
@@ -70,6 +70,9 @@ .SH ATTRIBUTES .TE .SH STANDARDS C11, POSIX.1-2008. +.P +ISO C and POSIX declare this function in +.IR <string.h> . .SH HISTORY POSIX.1-2001, C89, SVr4, 4.3BSD. .SH CAVEATS
man/man3/memcpy.3 +4 -1
@@ -13,7 +13,7 @@ .SH LIBRARY .RI ( libc ,\~ \-lc ) .SH SYNOPSIS .nf -.B #include <string.h> +.BR #include\~<memory.h> " // See STANDARDS" .P .BR "void *memcpy(" "size_t n;" .BI " void " dest "[restrict " n "], const void " src "[restrict " n ],
@@ -53,6 +53,9 @@ .SH ATTRIBUTES .TE .SH STANDARDS C11, POSIX.1-2008. +.P +ISO C and POSIX declare this function in +.IR <string.h> . .SH HISTORY POSIX.1-2001, C89, SVr4, 4.3BSD. .SH CAVEATS
man/man3/memfrob.3 +1 -1
@@ -13,7 +13,7 @@ .SH LIBRARY .SH SYNOPSIS .nf .BR "#define _GNU_SOURCE" " /* See feature_test_macros(7) */" -.B #include <string.h> +.B #include <memory.h> .P .BR "void *memfrob(" "size_t n;" .BI " void " s [ n "], size_t " n );
man/man3/memmem.3 +1 -1
@@ -13,7 +13,7 @@ .SH LIBRARY .SH SYNOPSIS .nf .BR "#define _GNU_SOURCE" " /* See feature_test_macros(7) */" -.B #include <string.h> +.B #include <memory.h> .P .BR "void *memmem(" "size_t hsize, size_t nsize;" .BI " const void " haystack [ hsize "], size_t " hsize ,
man/man3/memmove.3 +4 -1
@@ -12,7 +12,7 @@ .SH LIBRARY .RI ( libc ,\~ \-lc ) .SH SYNOPSIS .nf -.B #include <string.h> +.BR #include\~<memory.h> " // See STANDARDS" .P .BR "void *memmove(" "size_t n;" .BI " void " dest [ n "], const void " src [ n "], size_t " n );
@@ -56,6 +56,9 @@ .SH ATTRIBUTES .TE .SH STANDARDS C11, POSIX.1-2008. +.P +ISO C and POSIX declare this function in +.IR <string.h> . .SH HISTORY POSIX.1-2001, C89, SVr4, 4.3BSD. .SH SEE ALSO
man/man3/mempcpy.3 +1 -1
@@ -14,7 +14,7 @@ .SH LIBRARY .SH SYNOPSIS .nf .BR "#define _GNU_SOURCE" " /* See feature_test_macros(7) */" -.B #include <string.h> +.B #include <memory.h> .P .BR "void *mempcpy(" "size_t n;" .BI " void " dest "[restrict " n "], const void " src "[restrict " n ],
man/man3/memrchr.3 +1 -1
@@ -13,7 +13,7 @@ .SH LIBRARY .SH SYNOPSIS .nf .BR #define\~_GNU_SOURCE " // See feature_test_macros(7)" -.B #include <string.h> +.B #include <memory.h> .P .BR void\~*memrchr( size_t\~n; .BI " const void " s [ n "], int " c ", size_t " n );
man/man3/memset.3 +4 -1
@@ -12,7 +12,7 @@ .SH LIBRARY .RI ( libc ,\~ \-lc ) .SH SYNOPSIS .nf -.B #include <string.h> +.BR #include\~<memory.h> " // See STANDARDS" .P .BR "void *memset(" "size_t n;" .BI " void " s [ n "], int " c ", size_t " n );
@@ -48,6 +48,9 @@ .SH ATTRIBUTES .TE .SH STANDARDS C11, POSIX.1-2008. +.P +ISO C and POSIX declare this function in +.IR <string.h> . .SH HISTORY POSIX.1-2001, C89, SVr4, 4.3BSD. .SH SEE ALSO
man/man3/stpncpy.3 +7 -1
@@ -14,7 +14,7 @@ .SH LIBRARY .RI ( libc ,\~ \-lc ) .SH SYNOPSIS .nf -.B #include <string.h> +.BR #include\~<memory.h> " // See STANDARDS" .P .BR "char *strncpy(" "size_t dsize;" .BI " char " dst "[restrict " dsize "], const char *restrict " src ,
@@ -97,9 +97,15 @@ .SH STANDARDS .TP .BR strncpy () C11, POSIX.1-2008. +.IP +ISO C and POSIX declare this function in +.IR <string.h> . .TP .BR stpncpy () POSIX.1-2008. +.IP +POSIX declares this function in +.IR <string.h> . .SH HISTORY .TP .BR strncpy ()
man/man3/strcasecmp.3 +6 -0
@@ -15,6 +15,9 @@ .SH SYNOPSIS .B #include <strings.h> .P .BI "int strcasecmp(const char *" s1 ", const char *" s2 ); +.P +.BR #include\~<memory.h> " // See STANDARDS" +.P .BI "int strncasecmp(const char " s1 "[], const char " s2 "[], size_t " n ); .fi .SH DESCRIPTION
@@ -70,6 +73,9 @@ .SH ATTRIBUTES .TE .SH STANDARDS POSIX.1-2008. +.P +POSIX declares both functions in +.IR <string.h> . .SH HISTORY 4.4BSD, POSIX.1-2001. .P
man/man3/strcmp.3 +6 -0
@@ -16,6 +16,9 @@ .SH SYNOPSIS .B #include <string.h> .P .BI "int strcmp(const char *" s1 ", const char *" s2 ); +.P +.BR #include\~<memory.h> " // See STANDARDS" +.P .BR "int strncmp(const char " s1 "[], const char " s2 "[], size_t " n ); .fi .SH DESCRIPTION
@@ -107,6 +110,9 @@ .SH VERSIONS (If the two characters are equal, this difference is 0.) .SH STANDARDS C11, POSIX.1-2008. +.P +ISO C and POSIX declare both functions in +.IR <string.h> . .SH HISTORY POSIX.1-2001, C89, SVr4, 4.3BSD. .SH EXAMPLES
man/man3/strdup.3 +5 -0
@@ -16,6 +16,8 @@ .SH SYNOPSIS .P .BI "char *strdup(const char *" s ); .P +.BR #include\~<memory.h> " // See STANDARDS" +.P .BR "char *strndup(" "size_t n;" .BI " const char " s [ n "], size_t " n ); .fi
@@ -93,6 +95,9 @@ .SH ATTRIBUTES .TE .SH STANDARDS POSIX.1-2008. +.P +POSIX declares both functions in +.IR <string.h> . .SH HISTORY .TP .BR strdup ()
man/man3/strdupa.3 +4 -0
@@ -16,6 +16,10 @@ .SH SYNOPSIS .B #include <string.h> .P .BI "char *strdupa(const char *" s ); +.P +.BR "#define _GNU_SOURCE" " /* See feature_test_macros(7) */" +.B #include <memory.h> +.P .BR "char *strndupa(" "size_t n;" .BI " const char " s [ n "], size_t " n ); .fi
man/man3/strncat.3 +4 -1
@@ -11,7 +11,7 @@ .SH LIBRARY .RI ( libc ,\~ \-lc ) .SH SYNOPSIS .nf -.B #include <string.h> +.BR #include\~<memory.h> " // See STANDARDS" .P .BR "char *strncat(" "size_t ssize;" .BI " char *restrict " dst ", const char " src "[restrict " ssize ],
@@ -57,6 +57,9 @@ .SH ATTRIBUTES .TE .SH STANDARDS C11, POSIX.1-2008. +.P +ISO C and POSIX declare this function in +.IR <string.h> . .SH HISTORY POSIX.1-2001, C89, SVr4, 4.3BSD. .SH CAVEATS
man/man3/strnlen.3 +4 -1
@@ -12,7 +12,7 @@ .SH LIBRARY .RI ( libc ,\~ \-lc ) .SH SYNOPSIS .nf -.B #include <string.h> +.BR #include\~<memory.h> " // See STANDARDS" .P .BR "size_t strnlen(const char " s "[], size_t " maxlen ); .fi
@@ -83,6 +83,9 @@ .SH ATTRIBUTES .TE .SH STANDARDS POSIX.1-2008. +.P +ISO C and POSIX declare this function in +.IR <string.h> . .SH HISTORY POSIX.1-2008. .SH SEE ALSO
Signature · 1 line
2.53.0
Alejandro Colomar
maintainerPATCH 2/2 man/man*/{string.3,memory.h.3head}: Move functions to a new page memory.h(3head)
In reply to Alejandro ColomarSee previous commit.
--- man/man3/string.3 | 95 +++-------------------------------------- man/man3head/memory.h.3 | 57 +++++++++++++++++++++++++ 2 files changed, 62 insertions(+), 90 deletions(-) create mode 100644 man/man3head/memory.h.3
man/man3/string.3 +5 -90
@@ -5,7 +5,7 @@ .\" .TH string 3 (date) "Linux man-pages (unreleased)" .SH NAME -string \- byte operations +string \- string operations .SH LIBRARY Standard C library .RI ( libc ,\~ \-lc )
@@ -15,84 +15,25 @@ .SH SYNOPSIS .B #include <strings.h> .fi .SH DESCRIPTION -.SS Write -.TP -Write bytes -.RS -.TP -.BR bzero (3) -.TQ -.BR memset (3) -.RE .SS Copy .TP -Copy bytes -.RS -.TP -.BR memmove (3) -.TQ -.BR memcpy (3) -.TQ -.BR mempcpy (3) -.TQ -.BR memccpy (3) -.RE -.TP -Copy strings -.RS -.TP .BR strcpy (3) .TQ .BR stpcpy (3) -.RE -.TP -Copy nonstrings -.RS -.TP -.BR strncpy (3) -.RE .SS Catenate .TP -Catenate strings -.RS -.TP .BR strcat (3) -.RE -.TP -Catenate nonstrings -.RS -.TP -.BR strncat (3) -.RE .SS Duplicate .TP -Duplicate strings -.RS -.TP .BR strdup (3) .TQ .BR strdupa (3) -.RE -.TP -Duplicate nonstrings -.RS -.TP -.BR strndup (3) -.TQ -.BR strndupa (3) -.RE .SS Compare .TP -Compare bytes -.RS -.TP .BR memeq (3) -.TQ -.BR memcmp (3) -.RE -.TP -Compare strings -.RS +.IP +This function should be in +.IR <memory.h> . .TP .BR streq (3) .TQ
@@ -103,30 +44,8 @@ .SS Compare .BR strcoll (3) .TQ .BR strverscmp (3) -.RE -.TP -Compare nonstrings -.RS -.TP -.BR strncmp (3) -.TQ -.BR strncasecmp (3) -.RE .SS Search .TP -Search bytes -.RS -.TP -.BR memchr (3) -.TQ -.BR memrchr (3) -.TQ -.BR memmem (3) -.RE -.TP -Search strings -.RS -.TP .BR strlen (3) .TQ .BR strnul (3)
@@ -146,18 +65,14 @@ .SS Search .BR strspn (3) .TQ .BR strcspn (3) -.RE .SS Separate .TP -Separate strings -.RS -.TP .BR strsep (3) .TQ .BR strtok (3) -.RE .SS Others .TP .BR strxfrm (3) .SH SEE ALSO +.BR memory.h (3head), .BR string_copying (7)
man/man3head/memory.h.3 new file +57 -0
57 lines not on this page · raw message
Signature · 1 line
2.53.0
Alejandro Colomar
maintainerQuoted 11 lines
Date: 2026-07-31 23:18:54+0200
From: Alejandro Colomar <[email protected]>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).
Quoted 5 lines
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 <[email protected]>
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.
Signature · 1 line
<https://www.alejandro-colomar.es>
Re: [PATCH 1/2] man/man3/{mem,strn}*(): SYNOPSIS, STANDARDS: Document these as provided by <memory.h>
In reply to Alejandro ColomarI think it's irresponsible to use the man-pages project to promote personal idiosyncratic ideas like this in preference to what's been the standard location of functions since 1989.
I'd rather we add a mandatory deprecation warning to memory.h in glibc.
Signature · 2 lines
Joseph S. Myers [email protected]
Alejandro Colomar
maintainerRe: [PATCH 1/2] man/man3/{mem,strn}*(): SYNOPSIS, STANDARDS: Document these as provided by <memory.h>
Hi Joseph,
Quoted 8 lines
Date: 2026-07-31 21:23:35+0000
From: Joseph Myers <[email protected]>I think it's irresponsible to use the man-pages project to promote personal idiosyncratic ideas like this in preference to what's been the standard location of functions since 1989.
I'd rather we add a mandatory deprecation warning to
memory.hin glibc.
I hope you don't; it'd be a gratuitous breaking change.
Have a lovely night!
Alex
Signature · 1 line
<https://www.alejandro-colomar.es>
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>)
In reply to Joseph MyersHi Joseph,
Quoted 3 lines · Joseph Myers
I think it's irresponsible to use the man-pages project to promote personal idiosyncratic ideas like this in preference to what's been the standard location of functions since 1989.
I'm sure I don't need to bring to your attention what a mine field string/char sequence/memory buffer handling has been in C since the language's inception.
More to the point: what's a better forum for pursuing this attempt at reform that will both (a) reach a significant population of stakeholders who can variously red-team it and/or endorse it; and (b) has sufficient visibility that it can't easily be ignored by people who oppose reform in this area for whatever reason?
I hope you do not wish to imply that a closed session of some committee, or unofficial backroom politicking would be preferable, nor that WG14 should close its doors to members of its user community who have not been vetted for a disinclination to boat-rocking.
Regards,
Branden
Re: [PATCH 1/2] man/man3/{mem,strn}*(): SYNOPSIS, STANDARDS: Document these as provided by <memory.h>
In reply to Alejandro ColomarQuoted 5 lines · Alejandro Colomar
Hi Joseph,
Quoted 3 lines
Date: 2026-07-31 21:23:35+0000
From: Joseph Myers <[email protected]>
Quoted 8 lines
Quoted 5 lines
I think it's irresponsible to use the man-pages project to promote personal idiosyncratic ideas like this in preference to what's been the standard location of functions since 1989.
I'd rather we add a mandatory deprecation warning to
memory.hin glibc.I hope you don't; it'd be a gratuitous breaking change.
Yet this change has the same effect, just people will see it themselves rather than the compiler telling them, and go around sending patches to change it.
The man pages should reflect what the standard currently says, not what you'd like it to say. We had the same problem with e.g. stripping "C89" everywhere. People want it to reflect what the standard says.
Quoted 3 lines
Have a lovely night!
Alex
sam
Re: on the irresponsibility of pursuing C language reform
In reply to G. Branden RobinsonQuoted 11 lines · G. Branden Robinson
Hi Joseph,
Quoted 3 lines · Joseph Myers
I think it's irresponsible to use the man-pages project to promote personal idiosyncratic ideas like this in preference to what's been the standard location of functions since 1989.
I'm sure I don't need to bring to your attention what a mine field string/
charsequence/memory buffer handling has been in C since the language's inception.
Quoted 6 lines
More to the point: what's a better forum for pursuing this attempt at reform that will both (a) reach a significant population of stakeholders who can variously red-team it and/or endorse it; and (b) has sufficient visibility that it can't easily be ignored by people who oppose reform in this area for whatever reason?
I think the man page already tries to discourage use in its CAVEATS section.
Quoted 4 lines
I hope you do not wish to imply that a closed session of some committee, or unofficial backroom politicking would be preferable, nor that WG14 should close its doors to members of its user community who have not been vetted for a disinclination to boat-rocking.
I am confused as to where that implication could have possibly come from. Joseph is opposing the change in the form of a patch that is likely to be applied (*) to man-pages.git which has the effect of advocacy.
I don't think it has anything to do with WG14 membership or anything of the like? What am I missing?
(*) Alex has a history of making opinonated changes like this to man-pages, such as removing references to older standards, and using a somewhat novel (to many) syntax for prototypes.
Quoted 3 lines
Regards,
Branden
sam
Alejandro Colomar
maintainerRe: [PATCH 1/2] man/man3/{mem,strn}*(): SYNOPSIS, STANDARDS: Document these as provided by <memory.h>
In reply to Joseph MyersHi Joseph,
Quoted 6 lines
Date: 2026-07-31 21:23:35+0000
From: Joseph Myers <[email protected]>I think it's irresponsible to use the man-pages project to promote personal idiosyncratic ideas like this in preference to what's been the standard location of functions since 1989.
That's 37 years. During these 37 years we have gathered a lot of experience and data about this. And the conclusion is that it was a huge mistake. Programmers have struggled to understand this, and continue struggling. This is not about new programmers. This includes programmers that have been around for decades, including maintainers of core projects in which we all rely.
The move from <memory.h> to <string.h> seems to be entirely unjustified, and was unilateral by the C Committee for C89 (from what I can see).
It's easy to see that all these problems about string handling would probably be significantly less if these functions had never been moved to <string.h>.
I agree that changing stuff that has been unchanged for decades should usually be avoided, be done very carefully, and with strong justification. But in this case, it's justified, and doesn't break any existing or new code, because <memory.h> has been provided since forever.
Cheers,
Alex
Quoted 7 lines
I'd rather we add a mandatory deprecation warning to
memory.hin glibc.Signature · 2 lines
Joseph S. Myers [email protected]
Signature · 1 line
<https://www.alejandro-colomar.es>
Re: 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>)
In reply to G. Branden RobinsonQuoted 5 lines · G. Branden Robinson
More to the point: what's a better forum for pursuing this attempt at reform that will both (a) reach a significant population of stakeholders who can variously red-team it and/or endorse it; and (b) has sufficient visibility that it can't easily be ignored by people who oppose reform in this area for whatever reason?
man-pages should document the world of C APIs as it is, in a way that has broad community agreement; it should follow, not lead, on any changes.
When an API has been in <string.h> since 1989, that means documenting <string.h> as the main location for that API - not some other location one person thinks is better and that most of the community has never heard of.
Of course, where there is broad agreement on a deficiency in a particular API, it's entirely appropriate for man-pages to document it (for example, to warn against certain naive uses of strncpy or strncat and make clear the very specific use case those functions are intended for - but not to promote one person's idea of alternative names for those functions).
Signature · 2 lines
Joseph S. Myers [email protected]
Re: [PATCH 1/2] man/man3/{mem,strn}*(): SYNOPSIS, STANDARDS: Document these as provided by <memory.h>
In reply to Alejandro ColomarQuoted 3 lines · Alejandro Colomar
That's 37 years. During these 37 years we have gathered a lot of experience and data about this. And the conclusion is that it was a huge mistake. Programmers have struggled to understand this, and
No, there's no such conclusion. Two functions, strncpy and strncat, are with hindsight confusing (but it's the names and semantics rather than the header that are confusing). I don't think there's any kind of community consensus at all that there's any problem with mem* being in <string.h>, or any functions other than those two.
The committee writing C89 had to come up with a compromise between functions such as memcpy and strchr and functions such as bcopy and index. They chose to adopt memcpy and strchr, and chose to put them in <string.h>, and there's no evidence since then to suggest a problem with either choice.
Signature · 2 lines
Joseph S. Myers [email protected]
Alejandro Colomar
maintainerRe: [PATCH 1/2] man/man3/{mem,strn}*(): SYNOPSIS, STANDARDS: Document these as provided by <memory.h>
In reply to Sam JamesHi Sam,
Quoted 14 lines
Date: 2026-07-31 22:54:27+0100
From: Sam James <[email protected]>Quoted 9 lines · Alejandro Colomar
Hi Joseph,
Quoted 7 lines
Date: 2026-07-31 21:23:35+0000
From: Joseph Myers <[email protected]>I think it's irresponsible to use the man-pages project to promote personal idiosyncratic ideas like this in preference to what's been the standard location of functions since 1989.
Quoted 8 lines
Quoted 4 lines
Quoted 1 line
I'd rather we add a mandatory deprecation warning to
memory.hin glibc.I hope you don't; it'd be a gratuitous breaking change.
Yet this change has the same effect, just people will see it themselves rather than the compiler telling them, and go around sending patches to change it.
IME, people don't go changing includes unless they need something it's not available in the already-included header files.
Analysis of includes is quite complex, and there are tools for that --iwyu(1)--. As long as those tools don't start complaining --and they won't-- [1], I find it quite unlikely that people will start changing includes in existing code.
This is rather something that will affect new code (new source files).
[1] iwyu(1) works in a way that it allows a number of headers to
provide a symbol. If no header provides the symbol, then it will recommend the best header for it; but if a header that provides the symbol is already there, it won't complain.
Quoted 2 lines
The man pages should reflect what the standard currently says, not what you'd like it to say.
Not exactly; the standard is a good guideline, but sometimes it's off. We have vendor extensions, which are well documented, and when the standard is bogus, the extensions take over the page.
FWIW, the information from the standard is still there.
$ MANWIDTH=64 mansectf STANDARDS man3/memcpy.3 | cat memcpy(3) Library Functions Manual memcpy(3)
STANDARDS
C11, POSIX.1‐2008.
ISO C and POSIX declare this function in <string.h>.
Linux man‐pages (unreleased) (date) memcpy(3)
I've just removed it from the front of the page (SYNOPSIS), but it's still there, because of course, we must document the standard alongside the extension.
Quoted 2 lines
We had the same problem with e.g. stripping "C89"
everywhere.
Sorry for that one; it was a useful change, though. Now we have better manual pages than we had back then, regarding standards. I hope you realize about that. It triggered discussion, and a careful review of the text, which resulted in a good change after all.
Quoted 1 line
People want it to reflect what the standard says.
And it still does.
Have a lovely night!
Alex
Signature · 1 line
<https://www.alejandro-colomar.es>
Alejandro Colomar
maintainerRe: 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>)
In reply to Joseph MyersHi Joseph,
Quoted 11 lines
Date: 2026-07-31 22:10:13+0000
From: Joseph Myers <[email protected]>Quoted 5 lines · G. Branden Robinson
More to the point: what's a better forum for pursuing this attempt at reform that will both (a) reach a significant population of stakeholders who can variously red-team it and/or endorse it; and (b) has sufficient visibility that it can't easily be ignored by people who oppose reform in this area for whatever reason?
Quoted 6 lines
man-pages should document the world of C APIs as it is, in a way that has broad community agreement; it should follow, not lead, on any changes.
When an API has been in <
string.h> since 1989, that means documenting <string.h> as the main location for that API - not some other location one person thinks is better and that most of the community has never heard of.
FWIW, the APIs have been in <memory.h> since 1986 in 4.3BSD, and in System V they go back further to 1983.
Have a lovely night!
Alex
Signature · 1 line
<https://www.alejandro-colomar.es>
Re: on the irresponsibility of pursuing C language reform
In reply to Sam JamesHi Sam,
Quoted 10 lines · Sam James
Quoted 9 lines · G. Branden Robinson
Quoted 3 lines · Joseph Myers
I think it's irresponsible to use the man-pages project to promote personal idiosyncratic ideas like this in preference to what's been the standard location of functions since 1989.
I'm sure I don't need to bring to your attention what a mine field string/
charsequence/memory buffer handling has been in C since the language's inception.
Quoted 8 lines
Quoted 5 lines
More to the point: what's a better forum for pursuing this attempt at reform that will both (a) reach a significant population of stakeholders who can variously red-team it and/or endorse it; and (b) has sufficient visibility that it can't easily be ignored by people who oppose reform in this area for whatever reason?
I think the man page already tries to discourage use in its CAVEATS section.
Yes, but that's not a language reform, which is what Alex is pursuing with "alx-0097r1". In at least one earlier iteration he's expressed his intention to submit an N document to WG14.
Quoted 8 lines
Quoted 5 lines
I hope you do not wish to imply that a closed session of some committee, or unofficial backroom politicking would be preferable, nor that WG14 should close its doors to members of its user community who have not been vetted for a disinclination to boat-rocking.
I am confused as to where that implication could have possibly come from.
From familiarity with Alex's stated objective and rationale, which we can acquire from the recent list traffic Joseph characterized as irresponsible.
AC> The C Committee is discussing standardization of <memory.h>, so AC> let's give it a bump.
AC> I'll send you a copy of a paper I'm writing for the C Committee.
AC> It is at the bottom of this email. I will publish it as an N AC> document in August.
https://lore.kernel.org/linux-man/784288e704183a4297aeaa3d13af8edab18bc1ea.1785532392.git.alx@kernel.org/
https://lore.kernel.org/linux-man/amaTpQxd52iYjlor@devuan/
Quoted 3 lines
Joseph is opposing the change in the form of a patch that is likely to be applied (*) to man-pages.git which has the effect of advocacy.
Yes, and he said so categorically. More constructive advice might have taken the form of recommending a sequencing for staged changes. Here's a crude sketch.
1. Expand "CAVEATS" sections in relevant Linux man-pages documents. 2. Pursue N-document work with WG14. 3. When WG14 has disposed of that N-document (and any descendants
thereof), update Linux man-pages documents as appropriate.
Joseph's almost certainly better placed than I to add a "step 1.5" such that Alex might pursue some course that would better prepare the ground for his step 2. I haven't attempted revision of the C language standard myself, so I can't offer specific advice regarding how best to pursue such an objective. I possess only notions of elemental principles regarding how democratic, consultative bodies of technical experts _should_ serve the public.
That _is_ what we're here for, right?
Quoted 2 lines
I don't think it has anything to do with WG14 membership or anything of the like? What am I missing?
See above regarding Alex's publicly circulated drafts and expressed plans.
Quoted 3 lines
(*) Alex has a history of making opinonated changes like this to
man-pages, such as removing references to older standards, and using a somewhat novel (to many) syntax for prototypes.
I concur with that assessment. However, a person having a history of making opinionated changes is not sound grounds for evaluation of a technical proposal, especially if it's topically unrelated.
Preoccupying oneself with irrelevancies distracts from the conscientious execution of standards committee participation.
Regards,
Branden
Re: [PATCH 1/2] man/man3/{mem,strn}*(): SYNOPSIS, STANDARDS: Document these as provided by <memory.h>
In reply to Alejandro ColomarHi Alex,
Quoted 6 lines · Alejandro Colomar
Quoted 6 lines
Date: 2026-07-31 22:10:13+0000
From: Joseph Myers <[email protected]>
man-pages should document the world of C APIs as it is, in a way that has broad community agreement; it should follow, not lead, on any changes.
Quoted 7 lines
Quoted 4 lines
When an API has been in <
string.h> since 1989, that means documenting <string.h> as the main location for that API - not some other location one person thinks is better and that most of the community has never heard of.FWIW, the APIs have been in <
memory.h> since 1986 in 4.3BSD, and in System V they go back further to 1983.
I meant to respond earlier with this research tidbit, but I've been busy with preparing groff 1.25.0.rc2 and Mark Harris stepped in with much the same info. Thanks, Mark!
https://github.com/ryanwoodsmall/oldsysv/blob/master/sysv-pdp11_tape/usr/include/memory.h
Regards,
Branden
Alejandro Colomar
maintainerRe: [PATCH 1/2] man/man3/{mem,strn}*(): SYNOPSIS, STANDARDS: Document these as provided by <memory.h>
In reply to Joseph MyersHi Joseph,
Quoted 5 lines
Date: 2026-07-31 22:16:14+0000
From: Joseph Myers <[email protected]>On Sat, 1 Aug 2026, Alejandro Colomar wrote:
Quoted 7 lines
Quoted 3 lines
That's 37 years. During these 37 years we have gathered a lot of experience and data about this. And the conclusion is that it was a huge mistake. Programmers have struggled to understand this, and
No, there's no such conclusion. Two functions, strncpy and strncat, are with hindsight confusing (but it's the names and semantics rather than the header that are confusing).
Those are the most misused, indeed.
Quoted 3 lines
I don't think there's any kind of community
consensus at all that there's any problem with mem* being in <string.h>, or any functions other than those two.
But it's a consistent solution that keeps all existing functions (thus, not a breaking change), and puts them in a header file that is appropriate (and which has been their header since 1986).
Quoted 3 lines
The committee writing C89 had to come up with a compromise between functions such as memcpy and strchr and functions such as bcopy and index. They chose to adopt memcpy and strchr,
This was a good choice. mem*() were more portable back then.
Quoted 2 lines
and chose to put them in
<string.h>,
This wasn't a good choice. They were already in <memory.h> in existing systems.
Quoted 2 lines
and there's no evidence since then to suggest a problem with either choice.
We disagree.
Cheers,
Alex
Signature · 1 line
<https://www.alejandro-colomar.es>
Re: 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>)
In reply to Alejandro ColomarQuoted 6 lines · Alejandro Colomar
Quoted 3 lines
When an API has been in <
string.h> since 1989, that means documenting <string.h> as the main location for that API - not some other location one person thinks is better and that most of the community has never heard of.FWIW, the APIs have been in <
memory.h> since 1986 in 4.3BSD, and in System V they go back further to 1983.
In other words, they were in that header for 6 years, and it's been implicitly obsolescent by virtue of the standard choice for the 37 years since then.
Standards involve accepting agreed compromises that might not have been your first choice, rather than endlessly relitigating past disputes without new evidence or changed circumstances. In this case, the choice of where to put the functions in C89 was an agreed compromise that implicitly obsoleted the previous location, and should have put an end to any arguments that <string.h> was a bad location for those functions in the absence of clear new evidence. We have plenty of clear evidence for confusion about strn*; we don't about mem*.
Signature · 2 lines
Joseph S. Myers [email protected]
Alejandro Colomar
maintainerRe: 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>)
Hi Joseph,
Quoted 9 lines
Date: 2026-07-31 22:42:00+0000
From: Joseph Myers <[email protected]>Quoted 4 lines · Alejandro Colomar
Quoted 3 lines
When an API has been in <
string.h> since 1989, that means documenting <string.h> as the main location for that API - not some other location one person thinks is better and that most of the community has never heard of.
Quoted 6 lines
Quoted 2 lines
FWIW, the APIs have been in <
memory.h> since 1986 in 4.3BSD, and in System V they go back further to 1983.In other words, they were in that header for 6 years, and it's been implicitly obsolescent by virtue of the standard choice for the 37 years since then.
Yes. And I'm trying to revert the implicit obsolescence. Obsolescence isn't a one-way process. Sometimes, evidence shows up, and the obsolete feature must come back for $reasons.
FWIW, memccpy(3) was resurrected in C23 back from a cold death it had been suffering since forever. And that was less justified.
Quoted 7 lines
Standards involve accepting agreed compromises that might not have been your first choice, rather than endlessly relitigating past disputes without new evidence or changed circumstances. In this case, the choice of where to put the functions in C89 was an agreed compromise that implicitly obsoleted the previous location, and should have put an end to any arguments that <
string.h> was a bad location for those functions in the absence of clear new evidence.
I agree that it wasn't necessarily obvious back then that the movement to <string.h> was bad. While I blame the C89 Committee for other stuff they should have been aware of, this isn't one of them.
But now in 2026, we see that there have some been problems.
Quoted 2 lines
We have plenty of clear evidence for
confusion about strn*; we don't about mem*.
Thanks! Now we have a common ground.
Indeed, while there might be a minimal problem with mem*() --the fact of not starting by str makes them less misused--, the important problem is strn*().
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.
It wouldn't be reasonable to move strn*() to <memory.h>, and then leave mem*() in <string.h>, of course.
Similarly, it wouldn't be reasonable to more strncpy/cat() to <memory.h> and leave the rest of strn*() and all of mem*() in <string.h>.
This movement, while a bit massive, is consistent and self-explicative. That is, the only reasonable way to move strncpy/cat() is to also move strn*() and mem*().
Cheers,
Alex
Quoted 5 lines
Signature · 3 lines
-- Joseph S. Myers [email protected]
Signature · 1 line
<https://www.alejandro-colomar.es>
Re: [PATCH 1/2] man/man3/{mem,strn}*(): SYNOPSIS, STANDARDS: Document these as provided by <memory.h>
In reply to Joseph MyersHi Joseph,
Quoted 9 lines · Joseph Myers
Standards involve accepting agreed compromises that might not have been your first choice, rather than endlessly relitigating past disputes without new evidence or changed circumstances. In this case, the choice of where to put the functions in C89 was an agreed compromise that implicitly obsoleted the previous location, and should have put an end to any arguments that <
string.h> was a bad location for those functions in the absence of clear new evidence. We have plenty of clear evidence for confusion about strn*; we don't about mem*.
What are some good ways to gather evidence that:
* ...C programmers since 1989 have gotten better at recognizing when they're dealing with "memory buffers" versus "strings"?
* ...that the header file's name has aided or frustrated that recognition process?
* ...that consequences of whatever confusion persists are more severe than the C Committee measured in 1989?
You can tell by my phrasing which way I _suspect_ the evidence points, but I'll openly admit I don't have quantiative data.
But I think bringing such information to bear makes a stronger case than a simple appeal to 37 years of precedent.
Occasionally, matters get relitigated because they had been wrongly decided. I appreciate the trend since 2000 or so of Stroustrup (with respect to C++) and the Austin Group (with respect to POSIX) becoming more open about where the bodies are buried, and how certain standardization decisions have been reversed (through deprecation, withdrawal, and similar) because a powerful vendor took its leave and was no longer around to filibuster constructive development until its demands were met.
I seem to recall Stroustrup calling out Sun Microsystems by name in the 4th edition of his main C++ book. (Something to do with the exception propagation mechanism, I think.)
I suggest to WG14 that a good way to reduce relitigation is to candidly disclose in informative sections of the standard corresponding to applicable topics, where the committee as constituted at the time of issue has reached exhaustion with a matter. (Though I wonder if ISO would insist that such language be ripped out.)
I followed the C23 standarization process closely, and it looks as if the National Bodies (NB) very nearly fought WG14 to exhaustion regarding trigraphs. I was greatly relieved that you guys won that one.
Back to the topic at hand, in data processing we tend to strongly distinguish three forms of storage management:
1. base and bounds (mem*) 2. delimited (if with null bytes, str[^n]*) 3. fixed-field (strn*, but not very consistently)
From one perspective, 1 and 3 are really the same, but from another they're not, because, as some thousands of CVEs have shown, programmers thinking of case 3 tend to assume that the field will be populated with elements that are "well-behaved" in some way, whereas in case 1 they tend even more strongly to be conscious that the storage could be populated with arbitrary or even malicious garbage.
Do your impressions match mine in this area?
Regards,
Branden
Re: 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>)
In reply to Alejandro ColomarQuoted 7 lines · Alejandro Colomar
Quoted 3 lines
In other words, they were in that header for 6 years, and it's been implicitly obsolescent by virtue of the standard choice for the 37 years since then.
Yes. And I'm trying to revert the implicit obsolescence. Obsolescence isn't a one-way process. Sometimes, evidence shows up, and the obsolete feature must come back for $reasons.
When it's been obsolescent for 37 years, bringing back a header with the same name is just going to confuse people with 37 years of past information saying it's obsolescent (normally if one source says "use X" and another says "X is obsolescent", you can reliably assume that "X is obsolescent" is the more recent information, even without 37 years of history involved). Any reasonable change there would involve a new header, say <strnpad.h> for strncpy and strncat, rather than resurrecting a very old one.
Quoted 4 lines
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.
It's inconsistent with how people have understood C ever since it was standardized. Changing the header memcpy is in is just as ridiculous at this point as the proposal there once was to obsolesce NULL.
Quoted 5 lines
It wouldn't be reasonable to move strn*() to <
memory.h>, and then leave mem*() in <string.h>, of course.Similarly, it wouldn't be reasonable to more strncpy/cat() to <
memory.h> and leave the rest of strn*() and all of mem*() in <string.h>.
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.
Signature · 2 lines
Joseph S. Myers [email protected]
Alejandro Colomar
maintainerRe: on the irresponsibility of pursuing C language reform
In reply to G. Branden RobinsonHi Branden,
Quoted 22 lines
Date: 2026-07-31 17:24:17-0500
From: "G. Branden Robinson" <[email protected]>Hi Sam,
Quoted 16 lines · Sam James
Quoted 14 lines · G. Branden Robinson
Quoted 3 lines · Joseph Myers
I think it's irresponsible to use the man-pages project to promote personal idiosyncratic ideas like this in preference to what's been the standard location of functions since 1989.
I'm sure I don't need to bring to your attention what a mine field string/
charsequence/memory buffer handling has been in C since the language's inception.More to the point: what's a better forum for pursuing this attempt at reform that will both (a) reach a significant population of stakeholders who can variously red-team it and/or endorse it; and (b) has sufficient visibility that it can't easily be ignored by people who oppose reform in this area for whatever reason?
Quoted 6 lines
Quoted 2 lines
I think the man page already tries to discourage use in its CAVEATS section.
Yes, but that's not a language reform, which is what Alex is pursuing with "alx-0097r1". In at least one earlier iteration he's expressed his intention to submit an N document to WG14.
Indeed.
Quoted 16 lines
Quoted 8 lines
Quoted 5 lines
I hope you do not wish to imply that a closed session of some committee, or unofficial backroom politicking would be preferable, nor that WG14 should close its doors to members of its user community who have not been vetted for a disinclination to boat-rocking.
I am confused as to where that implication could have possibly come from.
From familiarity with Alex's stated objective and rationale, which we can acquire from the recent list traffic Joseph characterized as irresponsible.
AC> The C Committee is discussing standardization of <
memory.h>, so AC> let's give it a bump.
Quoted 7 lines
AC> I'll send you a copy of a paper I'm writing for the C Committee.
AC> It is at the bottom of this email. I will publish it as an N AC> document in August.
https://lore.kernel.org/linux-man/784288e704183a4297aeaa3d13af8edab18bc1ea.1785532392.git.alx@kernel.org/
https://lore.kernel.org/linux-man/amaTpQxd52iYjlor@devuan/
Thanks for posting the links. I've seen Doug was CCd on the second, so I've bounced him the patch set and alx-0097r1, in case he's interested.
Quoted 22 lines
Quoted 4 lines
Joseph is opposing the change in the form of a patch that is likely to be applied (*) to man-pages.git which has the effect of advocacy.
Yes, and he said so categorically. More constructive advice might have taken the form of recommending a sequencing for staged changes. Here's a crude sketch.
1. Expand "CAVEATS" sections in relevant Linux man-pages documents. 2. Pursue N-document work with WG14. 3. When WG14 has disposed of that N-document (and any descendantsthereof), update Linux man-pages documents as appropriate.
Joseph's almost certainly better placed than I to add a "step 1.5" such that Alex might pursue some course that would better prepare the ground for his step 2. I haven't attempted revision of the C language standard myself, so I can't offer specific advice regarding how best to pursue such an objective. I possess only notions of elemental principles regarding how democratic, consultative bodies of technical experts _should_ serve the public.
Quoted 1 line
That _is_ what we're here for, right?
Yes. Some more details:
I've obviously circulated this earlier within WG14, and CCd Keith and Mark in case they could clarify historic details, or were otherwise curious about/interested in the proposal.
Joseph stated opposition there (within WG14), and Keith Bostic suggested that I could change the manual pages to document <memory.h>, and use that to influence the public, in order to get to step 2. (The exact wording may differ.) Indeed, I thought it was a great idea, as <memory.h> is just as portable to POSIX-ish systems as <string.h> (except for gnulib and Illumos gate, gnulib is CCd, so hopefully they
address this portability issue).
Quoted 10 lines
Quoted 2 lines
I don't think it has anything to do with WG14 membership or anything of the like? What am I missing?
See above regarding Alex's publicly circulated drafts and expressed plans.
Quoted 3 lines
(*) Alex has a history of making opinonated changes like this to
man-pages, such as removing references to older standards, and using a somewhat novel (to many) syntax for prototypes.
Quoted 6 lines
I concur with that assessment. However, a person having a history of making opinionated changes is not sound grounds for evaluation of a technical proposal, especially if it's topically unrelated.
Preoccupying oneself with irrelevancies distracts from the conscientious execution of standards committee participation.
Thanks for the support! :)
Have a lovely night!
Alex
Signature · 1 line
<https://www.alejandro-colomar.es>
Re: [PATCH 1/2] man/man3/{mem,strn}*(): SYNOPSIS, STANDARDS: Document these as provided by <memory.h>
In reply to G. Branden RobinsonQuoted 2 lines · G. Branden Robinson
Occasionally, matters get relitigated because they had been wrongly decided. I appreciate the trend since 2000 or so of Stroustrup (with
That's a plausible description of Alejandro's attempt to relitigate realloc with size 0, in order to reduce UB. (Although in that case I think there have simply been too many changes, and so the semantics are irremediably confused regardless of any subsequent standard changes, and the best solution would involve a new function with a different name.)
I don't think it's a reasonable description for what are essentially stylistic matters, for anything as widely used as the header in which memcpy is declared or the NULL macro. That's in "would have spelt creat with an e" territory - things that could have been better with hindsight but where the cost outweighs any possible benefit at this stage in the language's life. "Avoiding UB" or "real user confusion" (in the case of strn*) are much better arguments than "slightly unaesthetic classification of functions into headers".
And I consider it an abuse of position to change man-pages to declare to users in general of C libraries on GNU/Linux that your standards proposal, at a very early stage (not even an N-document), is the One True Way of using the functions. It would be more neutral to say in the man pages that "as of July 2026, one member of WG14 has proposed moving these functions to <memory.h> [reference]; this proposal has not yet been considered by WG14". (I doubt the utility to users of describing proposed changes in man-pages at such an early stage, especially since the information would be long obsolete by the time those revisions of the pages make it into distributions, but it would at least more accurately reflect reality, and be vaguely neutral as long as you do it for *everyone's* open proposals, *including those you personally disagree with*, rather than privileging your own.)
Signature · 2 lines
Joseph S. Myers [email protected]
Re: [PATCH 1/2] man/man3/{mem,strn}*(): SYNOPSIS, STANDARDS: Document these as provided by <memory.h>)
In reply to Joseph MyersQuoted 8 lines · Joseph Myers
Quoted 6 lines · Alejandro Colomar
Quoted 3 lines
In other words, they were in that header for 6 years, and it's been implicitly obsolescent by virtue of the standard choice for the 37 years since then.
Yes. And I'm trying to revert the implicit obsolescence. Obsolescence isn't a one-way process. Sometimes, evidence shows up, and the obsolete feature must come back for $reasons.
Quoted 6 lines
When it's been obsolescent for 37 years, bringing back a header with the same name is just going to confuse people with 37 years of past information saying it's obsolescent (normally if one source says "use X" and another says "X is obsolescent", you can reliably assume that "X is obsolescent" is the more recent information, even without 37 years of history involved).
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]).
So how about <stdmem.h> or <stdmemory.h> for the standard mem* functions?
Quoted 3 lines
Any reasonable change there would involve a new header, say <
strnpad.h> for strncpy and strncat, rather than resurrecting a very old one.
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.
Quoted 7 lines
Quoted 4 lines
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.It's inconsistent with how people have understood C ever since it was standardized.
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.
C has single-handedly elevated "undefined behavior" into a field of academic study.
Quoted 7 lines
Quoted 6 lines
It wouldn't be reasonable to move strn*() to <
memory.h>, and then leave mem*() in <string.h>, of course.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>.
Quoted 5 lines
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.
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.
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).
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.hstring.hstdstrn.h
would sharply separate concerns and promote clearer reasoning among application developers.
Regards,
Branden
Alejandro Colomar
maintainerRe: 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>)
In reply to Joseph MyersHi Joseph,
Quoted 13 lines
Date: 2026-07-31 23:11:56+0000
From: Joseph Myers <[email protected]>Quoted 7 lines · Alejandro Colomar
Quoted 3 lines
In other words, they were in that header for 6 years, and it's been implicitly obsolescent by virtue of the standard choice for the 37 years since then.
Yes. And I'm trying to revert the implicit obsolescence. Obsolescence isn't a one-way process. Sometimes, evidence shows up, and the obsolete feature must come back for $reasons.
Quoted 6 lines
When it's been obsolescent for 37 years, bringing back a header with the same name is just going to confuse people with 37 years of past information saying it's obsolescent (normally if one source says "use X" and another says "X is obsolescent", you can reliably assume that "X is obsolescent" is the more recent information, even without 37 years of history involved).
This is highly speculative.
If the official documentation says use <memory.h>, use <memory.h>. Moreover, I've never seen anything saying <memory.h> is obsolescent. It's been only implicitly obsolescent, and most programmers don't even know <memory.h> exists at all. FWIW, I've sometimes seen it in the system headers, and eventually wondered why it was there, but nothing else. Thus, there's no contradicting information about it.
Quoted 2 lines
Any reasonable change there would involve a new
header, say <strnpad.h> for strncpy and strncat,
I think that misses that strn*() are still relatively misunderstood. It's only because they don't write that they aren't as dangerous.
But we would be much better with strprefix/suffix() and other related functions in <string.h> to even further remove uses of strn*() functions.
Moving the entirety of strn*() might be less urgent/important than moving strncpy/cat(), but it'd still be good to move them. They are all about handling [[gnu::nonstring]]s.
Quoted 2 lines
rather than resurrecting
a very old one.
I think the very old one is much better, because it can be used by virtually all programs already, since it already is there in all systems that matter, and already provides the functions were moving there. Apart from documentation, there's no real change.
On the other hand, if we were adding a new header, it'd have to be wrapped in #if __has_include(), and wouldn't be used until 10 years from now or so.
Quoted 8 lines
Quoted 4 lines
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.It's inconsistent with how people have understood C ever since it was standardized. Changing the header memcpy is in is just as ridiculous at this point as the proposal there once was to obsolesce NULL.
I disagree. Obsolescing NULL is a deeply breaking change. Standardizing an existing header file is just like standardizing an existing function. Nobody is saying <string.h> won't provide memcpy(3). My proposal to C2y says that <string.h> includes <memory.h>, so nothing changes. All of the existing understanding remains valid (although less preferred).
Quoted 11 lines
Quoted 5 lines
It wouldn't be reasonable to move strn*() to <
memory.h>, and then leave mem*() in <string.h>, of course.Similarly, it wouldn't be reasonable to more strncpy/cat() to <
memory.h> and leave the rest of strn*() and all of mem*() in <string.h>.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.
Did you read my alx-0096 paper? It shows how n2349 --which introduced memccpy(3) in C23-- is full of UB in examples introduced as
To avoid the risk of buffer overflow, the appropriate bound needs to be determined for each call and provided as an argument.
If memccpy(3) was standardized for reducing buffer overflows (which is implied, but not very explicitly said in the paper), it's ironic that the examples of how it's supposed to be used invoke UB. If the author of the paper can't avoid UB, you can guess it's a bomb as bad as strncpy(3) once was. And I'm not saying that memccpy(3) is bad, not that strncpy(3) is bad. I use strncpy(3) and know it's fine, and have been recently shown that memccpy(3) is actually good for implementing fgets(3). But it's not a function for copying strings, and n2349 is the ultimate proof. It is just as bad as strncpy(3) if misused for copying strings.
I'll paste here part of alx-0096, which clarifies how n2349 invokes UB.
Reading N2349 further, one finds an example of copying with
truncation:
char *p = memccpy (d, s1, '\0', dsize);
dsize -= (p - d - 1);
memccpy (p - 1, s2, '\0', dsize);
This is more prone to bugs than the case above, and more than
strncpy(3). Anyone suggesting to use this to improve safety
compared to strncpy(3), please, please, explain to me how they
think this can be safe in any way.
In fact, the code above is completely bogus, because if the
string is truncated, p will be NULL, and it invokes UB in
line 2. See how it was predictably prone to bugs? :)
At the bottom of the N2349 paper, there's a more correct --and
also more worrying-- example of how memccpy(3) could be used for
copying strings with truncation. This shows how terrible
memccpy(3) is for copying strings:
char *p = memccpy (d, s1, '\0', dsize);
if (p) {
--p;
p = memccpy (p, "/", '\0', dsize - (p - d));
if (p) {
--p;
p = memccpy (p, s2, '\0', dsize - (p - d));
}
}
if (!p)
d[dsize - 1] = '\0';
I think I don't need to explain what can go wrong in such
unreadable, brittle, and complex code.
...
Using a more suitable function --similar to POSIX's stpcpy(3)--,
this could be written much more safely:
char *p = d;
char *e = d + dsize;
p = stpecpy(p, e, s1);
p = stpecpy(p, e, "/");
p = stpecpy(p, e, s2);
if (p == NULL)
goto trunc; // The string was truncated
Here's how stpecpy() can be implemented for this:
char *
stpecpy(char *dst, const char *end, const char *restrict src)
{
ssize_t dlen;
if (dst == NULL)
return NULL;
dlen = strtcpy(dst, src, end - dst);
if (dlen == -1)
return NULL;
return dst + dlen;
}Cheers,
Alex
Signature · 1 line
<https://www.alejandro-colomar.es>
Re: [PATCH 1/2] man/man3/{mem, strn}*(): SYNOPSIS, STANDARDS: Document these as provided by <memory.h>
In reply to Joseph MyersQuoted 1 line · Joseph Myers
I'd rather we add a mandatory deprecation warning to
memory.hin glibc.
I would be for this change, and am surprised it has not already been done, to honest. The use of memory.h is a good indicator code hasn't been touched since the 80s.
Collin
Alejandro Colomar
maintainerRe: [PATCH 1/2] man/man3/{mem, strn}*(): SYNOPSIS, STANDARDS: Document these as provided by <memory.h>
Hi Collin,
Quoted 10 lines
Date: 2026-07-31 16:48:38-0700
From: Collin Funk <[email protected]>Quoted 1 line · Joseph Myers
I'd rather we add a mandatory deprecation warning to
memory.hin glibc.I would be for this change, and am surprised it has not already been done, to honest. The use of
memory.his a good indicator code hasn't been touched since the 80s.
Or that it has been touched in 2026. :)
Cheers,
Alex
Quoted 2 lines
Collin
Signature · 1 line
<https://www.alejandro-colomar.es>
Re: [PATCH 1/2] man/man3/{mem,strn}*(): SYNOPSIS, STANDARDS: Document these as provided by <memory.h>
In reply to Joseph MyersHi Joseph,
Quoted 4 lines · Joseph Myers
And I consider it an abuse of position to change man-pages to declare to users in general of C libraries on GNU/Linux that your standards proposal, at a very early stage (not even an N-document), is the One True Way of using the functions.
I agree that there is a _potential_ moral hazard here.
Quoted 10 lines
It would be more neutral to say in the man pages that "as of July 2026, one member of WG14 has proposed moving these functions to <
memory.h> [reference]; this proposal has not yet been considered by WG14". (I doubt the utility to users of describing proposed changes in man-pages at such an early stage, especially since the information would be long obsolete by the time those revisions of the pages make it into distributions, but it would at least more accurately reflect reality, and be vaguely neutral as long as you do it for *everyone's* open proposals, *including those you personally disagree with*, rather than privileging your own.)
I endorse this perspective. Another thing Alex could do is gate such readily-obsolescent stuff behind a *roff register so that it doesn't format (or, if one uses soelim(1), even populate the document sources), for _official releases_, but is still there for people pulling on Alex's Git repository.
My interpretation of Alex's tactics is that he feels energetic about his proposal, is willing to think it through carefully and advocate for it--these are good things--and that he wants to get it in front of domain experts and anneal it by fire before formally putting it before WG14--_also_ a good thing! In the meantime, he is the steward of a platform that _is_ topically implicated.
Such a position _can_ be abused, but it also seems not quite fair to me to expect him to stifle his advocacy in a _relevant_ forum.
Conventionally, what Alex faces is a potential conflict of interest. There are a variety of ways to cope with those. Foremost is disclosure to others of the potential conflict. That's such an important factor that I'd say it's 90% of the battle. Most of the time when people resist disclosing potential CofIs it's because they're self-dealing, they know it, and realize that disclosure would be self-incriminating.
There is another tier to the issue, and its recourse is recusal. We most often see this in the context of arbitration or in the judiciary.
However, Alex is not situated as a judge or gatekeeper here. To WG14, and to C library maintainers, he is an advocate. Has Alex rejected any proposed patches to the Linux man-pages along similar lines as his own advocacy? That would be gatekeeping.
Alex might consider deputizing a fellow maintainer to handle updates to portions of man pages where he has, or expects to have, business before WG14.
Regards,
Branden
Alejandro Colomar
maintainerRe: [PATCH 1/2] man/man3/{mem, strn}*(): SYNOPSIS, STANDARDS: Document these as provided by <memory.h>
In reply to Alejandro ColomarHi Collin,
Quoted 10 lines
Date: 2026-08-01 01:52:37+0200
From: Alejandro Colomar <[email protected]>Hi Collin,
Quoted 5 lines
Date: 2026-07-31 16:48:38-0700
From: Collin Funk <[email protected]>Joseph Myers <[email protected]> writes:
Quoted 7 lines
Quoted 5 lines
Quoted 1 line
I'd rather we add a mandatory deprecation warning to
memory.hin glibc.I would be for this change, and am surprised it has not already been done, to honest. The use of
memory.his a good indicator code hasn't been touched since the 80s.Or that it has been touched in 2026. :)
FWIW, a Debian code search shows 8.9k entries of 'include\s*<memory.h>', including for example in utils-linux, which is well maintained code.
That breaking change is well beyond what I think can be possibly done.
Cheers,
Alex
Quoted 9 lines
Cheers,
AlexQuoted 2 lines
Collin
Signature · 1 line
<https://www.alejandro-colomar.es>
Signature · 1 line
<https://www.alejandro-colomar.es>
Alejandro Colomar
maintainerRe: [PATCH 1/2] man/man3/{mem,strn}*(): SYNOPSIS, STANDARDS: Document these as provided by <memory.h>
In reply to G. Branden RobinsonHi Branden,
Quoted 40 lines
Date: 2026-07-31 18:57:47-0500
From: "G. Branden Robinson" <[email protected]>Hi Joseph,
Quoted 4 lines · Joseph Myers
And I consider it an abuse of position to change man-pages to declare to users in general of C libraries on GNU/Linux that your standards proposal, at a very early stage (not even an N-document), is the One True Way of using the functions.
I agree that there is a _potential_ moral hazard here.
Quoted 10 lines
It would be more neutral to say in the man pages that "as of July 2026, one member of WG14 has proposed moving these functions to <
memory.h> [reference]; this proposal has not yet been considered by WG14". (I doubt the utility to users of describing proposed changes in man-pages at such an early stage, especially since the information would be long obsolete by the time those revisions of the pages make it into distributions, but it would at least more accurately reflect reality, and be vaguely neutral as long as you do it for *everyone's* open proposals, *including those you personally disagree with*, rather than privileging your own.)I endorse this perspective. Another thing Alex could do is gate such readily-obsolescent stuff behind a *roff register so that it doesn't format (or, if one uses soelim(1), even populate the document sources), for
_officialreleases_, but is still there for people pulling on Alex's Git repository.My interpretation of Alex's tactics is that he feels energetic about his proposal, is willing to think it through carefully and advocate for it--these are good things--and that he wants to get it in front of domain experts and anneal it by fire before formally putting it before WG14--_also_ a good thing! In the meantime, he is the steward of a platform that _is_ topically implicated.
Such a position _can_ be abused, but it also seems not quite fair to me to expect him to stifle his advocacy in a _relevant_ forum.
Quoted 6 lines
Conventionally, what Alex faces is a potential conflict of interest. There are a variety of ways to cope with those. Foremost is disclosure to others of the potential conflict. That's such an important factor that I'd say it's 90% of the battle. Most of the time when people resist disclosing potential CofIs it's because they're self-dealing, they know it, and realize that disclosure would be self-incriminating.
Indeed. While I haven't explicitly mentioned CofI, I haven't hidden it either, and have mentioned all the relevant information. If I haven't merged this single-handedly, it's precisely because I think there could be some, and want to get feedback.
Cheers,
Alex
Quoted 15 lines
There is another tier to the issue, and its recourse is recusal. We most often see this in the context of arbitration or in the judiciary.
However, Alex is not situated as a judge or gatekeeper here. To WG14, and to C library maintainers, he is an advocate. Has Alex rejected any proposed patches to the Linux man-pages along similar lines as his own advocacy? That would be gatekeeping.
Alex might consider deputizing a fellow maintainer to handle updates to portions of man pages where he has, or expects to have, business before WG14.
Regards,
Branden
Signature · 1 line
<https://www.alejandro-colomar.es>
Alejandro Colomar
maintainerRe: [PATCH 1/2] man/man3/{mem,strn}*(): SYNOPSIS, STANDARDS: Document these as provided by <memory.h>
In reply to Alejandro ColomarHi Sam,
Quoted 6 lines
Date: 2026-08-01 00:19:03+0200
From: Alejandro Colomar <[email protected]>Quoted 3 lines
Date: 2026-07-31 22:54:27+0100
From: Sam James <[email protected]>
[...]
Quoted 3 lines
Quoted 1 line
People want it to reflect what the standard says.
And it still does.
Hmmm, this has implications. The functions that are non-standard, can be changed as of now, because, well, there's no standard saying otherwise.
Maybe that's a good move. A commit now changing the following functions the be documented as provided by <memory.h>, without any mentions to <string.h>, simply because there's no standard mandating otherwise:
- strndupa(3) - mempcpy(3) - memrchr(3) - memmem(3) - memfrob(3)
Which is a nice introduction for this header file.
Then we can leave discussion of the standard functions for later. If what the standard says is the problem, let's focus on what it doesn't say.
Cheers,
Alex
Signature · 1 line
<https://www.alejandro-colomar.es>
Alejandro Colomar
maintainerPATCH v2 1/1 man/man3/mem*(): SYNOPSIS: Document non-standard mem*() functions as provided by <memory.h>
In reply to Alejandro ColomarThey've been provided there since forever, and that's a more appropriate header.
While it would be good to document the standard functions also as provided by <memory.h>, that's more controversial, and is still being litigated.
---
Hi!
Here's a less ambitious change. It's not that I don't want to pursue the other one, but that this one will likely pass more quickly.
This only changes documentation for non-standard functions, where the argument that the standard says XXX is now irrelevant.
Have a lovely night!
Alex
man/man3/memfrob.3 | 2 +- man/man3/memmem.3 | 2 +- man/man3/mempcpy.3 | 2 +- man/man3/memrchr.3 | 2 +- man/man3/strdupa.3 | 4 ++++ 5 files changed, 8 insertions(+), 4 deletions(-)
man/man3/memfrob.3 +1 -1
@@ -13,7 +13,7 @@ .SH LIBRARY .SH SYNOPSIS .nf .BR "#define _GNU_SOURCE" " /* See feature_test_macros(7) */" -.B #include <string.h> +.B #include <memory.h> .P .BR "void *memfrob(" "size_t n;" .BI " void " s [ n "], size_t " n );
man/man3/memmem.3 +1 -1
@@ -13,7 +13,7 @@ .SH LIBRARY .SH SYNOPSIS .nf .BR "#define _GNU_SOURCE" " /* See feature_test_macros(7) */" -.B #include <string.h> +.B #include <memory.h> .P .BR "void *memmem(" "size_t hsize, size_t nsize;" .BI " const void " haystack [ hsize "], size_t " hsize ,
man/man3/mempcpy.3 +1 -1
@@ -14,7 +14,7 @@ .SH LIBRARY .SH SYNOPSIS .nf .BR "#define _GNU_SOURCE" " /* See feature_test_macros(7) */" -.B #include <string.h> +.B #include <memory.h> .P .BR "void *mempcpy(" "size_t n;" .BI " void " dest "[restrict " n "], const void " src "[restrict " n ],
man/man3/memrchr.3 +1 -1
@@ -13,7 +13,7 @@ .SH LIBRARY .SH SYNOPSIS .nf .BR #define\~_GNU_SOURCE " // See feature_test_macros(7)" -.B #include <string.h> +.B #include <memory.h> .P .BR void\~*memrchr( size_t\~n; .BI " const void " s [ n "], int " c ", size_t " n );
man/man3/strdupa.3 +4 -0
@@ -16,6 +16,10 @@ .SH SYNOPSIS .B #include <string.h> .P .BI "char *strdupa(const char *" s ); +.P +.BR "#define _GNU_SOURCE" " /* See feature_test_macros(7) */" +.B #include <memory.h> +.P .BR "char *strndupa(" "size_t n;" .BI " const char " s [ n "], size_t " n ); .fi
base-commit: 8152eb52d9a92f02c14e843545acec7ee1946479
Signature · 1 line
2.53.0
Alejandro Colomar
maintainerRe: on the irresponsibility of pursuing C language reform
In reply to Sam JamesHi Sam,
Quoted 6 lines
Date: 2026-07-31 22:59:47+0100
From: Sam James <[email protected]>(*) Alex has a history of making opinonated changes like this to man-pages, such as removing references to older standards, and using a somewhat novel (to many) syntax for prototypes.
I think this comment deserves a well thought response.
"Opinionated" is your subjective knee-jerk way of saying it. I don't agree with it.
I'd say I have a history of making changes based on thorough revision of history and technical merits, even when that research is contrary to decades (or half-centuries) of common practice, and possibly to current or withdrawn standards.
In this case, and I don't mean this specific patch set, but the years- long revision of string documentation that I've been carrying out, we have a conflict between the design and correct use of string and memory functions, and their common use today.
The functions that are most subject to this conflict are strncpy(3), strncat(3), and memccpy(3). But the rest of strn*() are also somewhat affected, and the rest of mem*() minorly affected.
They were originally designed for a specific use case for which they were great. This knowledge has been lost in time, and I've been working to recover that knowledge.
Precisely because of standards and other documentation that isn't written with the level of care that I have, we have decades of misuses of strncpy(3) and strncat(3).
Moreover, it's in other places that you should be complaining about. GCC has a bogus set of diagnostics about strncpy(3) and strncat(3), which we could very well call opinionated, and I haven't seen anyone reporting them as bogus before I did. Those diagnostics have not been considered opinionated, just because they follow mainstream (bogus) usage of these functions, but they are indeed forcing an opinion of how these functions should be used over other uses that may be more uncommon but which are actually the original and correct uses of these functions.
<https://inbox.sourceware.org/gcc/[email protected]/>
<https://gcc.gnu.org/bugzilla/show_bug.cgi?id=123024>
<https://gcc.gnu.org/bugzilla/show_bug.cgi?id=122963>
It's curious that you called the GCC diagnostic "heuristics" instead of "opinionated". There's nothing about heuristics there. It's just an enforcement of an (incorrect) opinion about how these functions should be used.
And since C23, we're seeing that the same story is repeating with memccpy(3), which was once a niche function that was great for implementing fgets(3), and now is misused by everyone and their dog for copying strings with truncation.
I have spent probably more time than anyone in the last 5 years researching about string handling, and have proven the correctness of my research in the shadow-utils project, where most of my work has been in revising string and memory handling code. I've fixed uncountable subtle bugs in such code, and have made the resulting code actually readable. And the number of accidental regressions is minimal (IIRC, one or two regressions related to string and memory handling, in all that time, and not too dangerous).
Thus, I think it is my responsibility, as maintainer of the documentation project most read by C programmers, to let our audience learn what I've learnt in these years, and allow them to write safe string- and memory-handling code.
It is thanks to this years-long research that I've been able to gather important knowledge from people like Mark Harris, Doug McIlroy, Branden, and many others, who hold knowledge that few other programmers possess, and spread it to the world.
I'd consider it a negligence to do the easy thing and follow what standards say, or what most programmers do, because that's what has led us to the well-known mistakes that C programmers make.
FWIW, regarding the possible conflict of interest that was mentioned yesterday, I'll say that I don't get paid for my contributions to ISO C as a member of WG14. There's no benefit to me other than public recognition. I'll also disclose the exact quantity that I've been paid for maintaining the Linux man-pages project:
110 kUSD in 2025 (from 5 sponsors) 75 kUSD in 2026 (from 3 sponsors)
I'm convinced that that doesn't have any effects in my decisions here, as I've had a consistent record of decisions well before I had any economic benefits from maintaining this project. None of those sponsors have expressed any interest in favour of these decisions (nor against).
I'll rumiate a bit more on these patches, and probably make minor changes to them, but the essence of documenting <memory.h> for all of mem*() and strn*() in SYNOPSIS is most likely to be eventually merged. I'll be careful to document what the standards say in a way that isn't confusing to users, and also in general will try to document it in a way that is positive for our audience --even if some of that audience may have knee-jerk reactions, like you are having at the moment--. I have also received very positive feedback for other changes for which some people have noisily had knee-jerk reactions. I believe it is my duty as maintainer of this project to do this change.
Have a lovely day!
Alex
Signature · 1 line
<https://www.alejandro-colomar.es>
Alejandro Colomar
maintainerRe: on the irresponsibility of pursuing C language reform
Quoted 110 lines
Date: 2026-08-01 14:01:39+0200
From: Alejandro Colomar <[email protected]>Hi Sam,
Quoted 6 lines
Date: 2026-07-31 22:59:47+0100
From: Sam James <[email protected]>(*) Alex has a history of making opinonated changes like this to man-pages, such as removing references to older standards, and using a somewhat novel (to many) syntax for prototypes.
I think this comment deserves a well thought response.
"Opinionated" is your subjective knee-jerk way of saying it. I don't agree with it.
I'd say I have a history of making changes based on thorough revision of history and technical merits, even when that research is contrary to decades (or half-centuries) of common practice, and possibly to current or withdrawn standards.
In this case, and I don't mean this specific patch set, but the years- long revision of string documentation that I've been carrying out, we have a conflict between the design and correct use of string and memory functions, and their common use today.
The functions that are most subject to this conflict are strncpy(3), strncat(3), and memccpy(3). But the rest of strn*() are also somewhat affected, and the rest of mem*() minorly affected.
They were originally designed for a specific use case for which they were great. This knowledge has been lost in time, and I've been working to recover that knowledge.
Precisely because of standards and other documentation that isn't written with the level of care that I have, we have decades of misuses of strncpy(3) and strncat(3).
Moreover, it's in other places that you should be complaining about. GCC has a bogus set of diagnostics about strncpy(3) and strncat(3), which we could very well call opinionated, and I haven't seen anyone reporting them as bogus before I did. Those diagnostics have not been considered opinionated, just because they follow mainstream (bogus) usage of these functions, but they are indeed forcing an opinion of how these functions should be used over other uses that may be more uncommon but which are actually the original and correct uses of these functions.
<https://inbox.sourceware.org/gcc/[email protected]/>
<https://gcc.gnu.org/bugzilla/show_bug.cgi?id=123024>
<https://gcc.gnu.org/bugzilla/show_bug.cgi?id=122963>It's curious that you called the GCC diagnostic "heuristics" instead of "opinionated". There's nothing about heuristics there. It's just an enforcement of an (incorrect) opinion about how these functions should be used.
And since C23, we're seeing that the same story is repeating with memccpy(3), which was once a niche function that was great for implementing fgets(3), and now is misused by everyone and their dog for copying strings with truncation.
I have spent probably more time than anyone in the last 5 years researching about string handling, and have proven the correctness of my research in the shadow-utils project, where most of my work has been in revising string and memory handling code. I've fixed uncountable subtle bugs in such code, and have made the resulting code actually readable. And the number of accidental regressions is minimal (IIRC, one or two regressions related to string and memory handling, in all that time, and not too dangerous).
Thus, I think it is my responsibility, as maintainer of the documentation project most read by C programmers, to let our audience learn what I've learnt in these years, and allow them to write safe string- and memory-handling code.
It is thanks to this years-long research that I've been able to gather important knowledge from people like Mark Harris, Doug McIlroy, Branden, and many others, who hold knowledge that few other programmers possess, and spread it to the world.
I'd consider it a negligence to do the easy thing and follow what standards say, or what most programmers do, because that's what has led us to the well-known mistakes that C programmers make.
FWIW, regarding the possible conflict of interest that was mentioned yesterday, I'll say that I don't get paid for my contributions to ISO C as a member of WG14. There's no benefit to me other than public recognition. I'll also disclose the exact quantity that I've been paid for maintaining the Linux man-pages project:
110 kUSD in 2025 (from 5 sponsors) 75 kUSD in 2026 (from 3 sponsors)I'm convinced that that doesn't have any effects in my decisions here, as I've had a consistent record of decisions well before I had any economic benefits from maintaining this project. None of those sponsors have expressed any interest in favour of these decisions (nor against).
I'll rumiate a bit more on these patches, and probably make minor changes to them, but the essence of documenting <
memory.h> for all of mem*() and strn*() in SYNOPSIS is most likely to be eventually merged. I'll be careful to document what the standards say in a way that isn't confusing to users, and also in general will try to document it in a way that is positive for our audience --even if some of that audience may have knee-jerk reactions, like you are having at the moment--. I have also received very positive feedback for other changes for which some people have noisily had knee-jerk reactions. I believe it is my duty as maintainer of this project to do this change.
Quoted 5 lines
Have a lovely day!
AlexSignature · 1 line
<https://www.alejandro-colomar.es>
And of course, I'm not dismissing that I may make mistakes in early drafts of decisions, and sometimes take decisions before thinking enough, but I have a good record of revising my own decisions when they were mistaken.
Cheers,
Alex
Signature · 1 line
<https://www.alejandro-colomar.es>
Re: 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>)
In reply to Alejandro ColomarBranden wrote
Quoted 3 lines
I'm sure I don't need to bring to your attention what a mine field string/
charsequence/memory buffer handling has been in C since the language's inception.
Yes, this is a property of the language, not a peculiar deficiency of the <string.h> functions. As I see it, patching up perceived deficiencies of the functions adds complexity to the language definition and to the task of code-reading, with little real benefit.
Doug
Quoted 178 lines · Alejandro Colomar
Hi Joseph,
Quoted 13 lines
Date: 2026-07-31 23:11:56+0000
From: Joseph Myers <[email protected]>Quoted 7 lines · Alejandro Colomar
Quoted 3 lines
In other words, they were in that header for 6 years, and it's been implicitly obsolescent by virtue of the standard choice for the 37 years since then.
Yes. And I'm trying to revert the implicit obsolescence. Obsolescence isn't a one-way process. Sometimes, evidence shows up, and the obsolete feature must come back for $reasons.
Quoted 6 lines
When it's been obsolescent for 37 years, bringing back a header with the same name is just going to confuse people with 37 years of past information saying it's obsolescent (normally if one source says "use X" and another says "X is obsolescent", you can reliably assume that "X is obsolescent" is the more recent information, even without 37 years of history involved).
This is highly speculative.
If the official documentation says use <
memory.h>, use <memory.h>. Moreover, I've never seen anything saying <memory.h> is obsolescent. It's been only implicitly obsolescent, and most programmers don't even know <memory.h> exists at all. FWIW, I've sometimes seen it in the system headers, and eventually wondered why it was there, but nothing else. Thus, there's no contradicting information about it.Quoted 2 lines
Any reasonable change there would involve a new
header, say <strnpad.h> for strncpy and strncat,I think that misses that strn*() are still relatively misunderstood. It's only because they don't write that they aren't as dangerous.
But we would be much better with strprefix/suffix() and other related functions in <
string.h> to even further remove uses of strn*() functions.Moving the entirety of strn*() might be less urgent/important than moving strncpy/cat(), but it'd still be good to move them. They are all about handling [[gnu::nonstring]]s.
Quoted 2 lines
rather than resurrecting
a very old one.I think the very old one is much better, because it can be used by virtually all programs already, since it already is there in all systems that matter, and already provides the functions were moving there. Apart from documentation, there's no real change.
On the other hand, if we were adding a new header, it'd have to be wrapped in #if
__has_include(), and wouldn't be used until 10 years from now or so.Quoted 8 lines
Quoted 4 lines
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.It's inconsistent with how people have understood C ever since it was standardized. Changing the header memcpy is in is just as ridiculous at this point as the proposal there once was to obsolesce NULL.
I disagree. Obsolescing NULL is a deeply breaking change. Standardizing an existing header file is just like standardizing an existing function. Nobody is saying <
string.h> won't provide memcpy(3). My proposal to C2y says that <string.h> includes <memory.h>, so nothing changes. All of the existing understanding remains valid (although less preferred).Quoted 11 lines
Quoted 5 lines
It wouldn't be reasonable to move strn*() to <
memory.h>, and then leave mem*() in <string.h>, of course.Similarly, it wouldn't be reasonable to more strncpy/cat() to <
memory.h> and leave the rest of strn*() and all of mem*() in <string.h>.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.Did you read my alx-0096 paper? It shows how n2349 --which introduced memccpy(3) in C23-- is full of UB in examples introduced as
To avoid the risk of buffer overflow, the appropriate bound needs to be determined for each call and provided as an argument.
If memccpy(3) was standardized for reducing buffer overflows (which is implied, but not very explicitly said in the paper), it's ironic that the examples of how it's supposed to be used invoke UB. If the author of the paper can't avoid UB, you can guess it's a bomb as bad as strncpy(3) once was. And I'm not saying that memccpy(3) is bad, not that strncpy(3) is bad. I use strncpy(3) and know it's fine, and have been recently shown that memccpy(3) is actually good for implementing fgets(3). But it's not a function for copying strings, and n2349 is the ultimate proof. It is just as bad as strncpy(3) if misused for copying strings.
I'll paste here part of alx-0096, which clarifies how n2349 invokes UB.
Reading N2349 further, one finds an example of copying with truncation: char *p = memccpy (d, s1, '\0', dsize); dsize -= (p - d - 1); memccpy (p - 1, s2, '\0', dsize); This is more prone to bugs than the case above, and more than strncpy(3). Anyone suggesting to use this to improve safety compared to strncpy(3), please, please, explain to me how they think this can be safe in any way. In fact, the code above is completely bogus, because if the string is truncated, p will be NULL, and it invokes UB in line 2. See how it was predictably prone to bugs? :) At the bottom of the N2349 paper, there's a more correct --and also more worrying-- example of how memccpy(3) could be used for copying strings with truncation. This shows how terrible memccpy(3) is for copying strings: char *p = memccpy (d, s1, '\0', dsize); if (p) { --p; p = memccpy (p, "/", '\0', dsize - (p - d)); if (p) { --p; p = memccpy (p, s2, '\0', dsize - (p - d)); } } if (!p) d[dsize - 1] = '\0'; I think I don't need to explain what can go wrong in such unreadable, brittle, and complex code. ... Using a more suitable function --similar to POSIX's stpcpy(3)--, this could be written much more safely: char *p = d; char *e = d + dsize; p = stpecpy(p, e, s1); p = stpecpy(p, e, "/"); p = stpecpy(p, e, s2); if (p == NULL) goto trunc; // The string was truncated Here's how stpecpy() can be implemented for this: char * stpecpy(char *dst, const char *end, const char *restrict src) { ssize_t dlen; if (dst == NULL) return NULL; dlen = strtcpy(dst, src, end - dst); if (dlen == -1) return NULL; return dst + dlen; }Cheers,
Alex
Alejandro Colomar
maintainerRe: [PATCH 1/2] man/man3/{mem,strn}*(): SYNOPSIS, STANDARDS: Document these as provided by <memory.h>)
In reply to G. Branden RobinsonHi Branden,
Quoted 3 lines
Date: 2026-07-31 18:32:53-0500
From: "G. Branden Robinson" <[email protected]>
[...]
Quoted 7 lines
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]).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.
Quoted 8 lines
Quoted 3 lines
Any reasonable change there would involve a new header, say <
strnpad.h> for strncpy and strncat, rather than resurrecting a very old one.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.
Quoted 29 lines
Quoted 7 lines
Quoted 4 lines
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.It's inconsistent with how people have understood C ever since it was standardized.
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.
C has single-handedly elevated "undefined behavior" into a field of academic study.
Quoted 7 lines
Quoted 6 lines
It wouldn't be reasonable to move strn*() to <
memory.h>, and then leave mem*() in <string.h>, of course.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>.Quoted 5 lines
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.
Quoted 3 lines
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
Quoted 4 lines
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
Quoted 11 lines
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.hstring.hstdstrn.hwould 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
Quoted 5 lines
Regards,
Branden
Signature · 1 line
<https://www.alejandro-colomar.es>
Re: [PATCH 1/2] man/man3/{mem,strn}*(): SYNOPSIS, STANDARDS: Document these as provided by <memory.h>)
In reply to G. Branden RobinsonHi,
Quoted 11 lines · G. Branden Robinson
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.hstring.hstdstrn.hwould 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. 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. If we are going to introduce a new separation, let us make it a good one.
Christopher
Re: on the irresponsibility of pursuing C language reform
In reply to Alejandro ColomarQuoted 5 lines · Alejandro Colomar
Hi Sam,
Quoted 3 lines
Date: 2026-07-31 22:59:47+0100
From: Sam James <[email protected]>
Quoted 8 lines
Quoted 3 lines
(*) Alex has a history of making opinonated changes like this to man-pages, such as removing references to older standards, and using a somewhat novel (to many) syntax for prototypes.
I think this comment deserves a well thought response.
"Opinionated" is your subjective knee-jerk way of saying it. I don't agree with it.
I don't consider it kneejerk. It's an opinion I've formed over the years. You're of course free to disagre with it.
Quoted 5 lines
I'd say I have a history of making changes based on thorough revision of history and technical merits, even when that research is contrary to decades (or half-centuries) of common practice, and possibly to current or withdrawn standards.
The primary issue I have is that I don't often see you change your mind or acknowledge that being the man-pages maintainer is a privileged position, or separate your desires from the maintainership role.
When I'm acting in a maintainer role, I often take changes I don't particularly agree with if they're technically sound and there's broad consensus for them. I think many do.
Quoted 6 lines
In this case, and I don't mean this specific patch set, but the years- long revision of string documentation that I've been carrying out, we have a conflict between the design and correct use of string and memory functions, and their common use today.
Yes, I don't dispute that the terminology is poor.
Quoted 8 lines
The functions that are most subject to this conflict are strncpy(3), strncat(3), and memccpy(3). But the rest of strn*() are also somewhat affected, and the rest of mem*() minorly affected.
They were originally designed for a specific use case for which they were great. This knowledge has been lost in time, and I've been working to recover that knowledge.
Quoted 5 lines
Precisely because of standards and other documentation that isn't written with the level of care that I have, we have decades of misuses of strncpy(3) and strncat(3).
Moreover, it's in other places that you should be complaining about.
I do complain about those, and we finally got some consensus on the GCC side on not warning about a bunch of them by default, even.
Quoted 11 lines
GCC has a bogus set of diagnostics about strncpy(3) and strncat(3), which we could very well call opinionated, and I haven't seen anyone reporting them as bogus before I did. Those diagnostics have not been considered opinionated, just because they follow mainstream (bogus) usage of these functions, but they are indeed forcing an opinion of how these functions should be used over other uses that may be more uncommon but which are actually the original and correct uses of these functions.
<https://inbox.sourceware.org/gcc/[email protected]/>
<https://gcc.gnu.org/bugzilla/show_bug.cgi?id=123024>
<https://gcc.gnu.org/bugzilla/show_bug.cgi?id=122963>
Quoted 4 lines
It's curious that you called the GCC diagnostic "heuristics" instead of "opinionated". There's nothing about heuristics there. It's just an enforcement of an (incorrect) opinion about how these functions should be used.
The warnings are both opinionated and heuristics-based. I'm not sure how you could read the comment you linked to as somehow an endorsement of the status quo, I've been quite vocal about changing it elsewhere too?
Quoted 29 lines
And since C23, we're seeing that the same story is repeating with memccpy(3), which was once a niche function that was great for implementing fgets(3), and now is misused by everyone and their dog for copying strings with truncation.
I have spent probably more time than anyone in the last 5 years researching about string handling, and have proven the correctness of my research in the shadow-utils project, where most of my work has been in revising string and memory handling code. I've fixed uncountable subtle bugs in such code, and have made the resulting code actually readable. And the number of accidental regressions is minimal (IIRC, one or two regressions related to string and memory handling, in all that time, and not too dangerous).
Thus, I think it is my responsibility, as maintainer of the documentation project most read by C programmers, to let our audience learn what I've learnt in these years, and allow them to write safe string- and memory-handling code.
It is thanks to this years-long research that I've been able to gather important knowledge from people like Mark Harris, Doug McIlroy, Branden, and many others, who hold knowledge that few other programmers possess, and spread it to the world.
I'd consider it a negligence to do the easy thing and follow what standards say, or what most programmers do, because that's what has led us to the well-known mistakes that C programmers make.
Quoted 5 lines
FWIW, regarding the possible conflict of interest that was mentioned yesterday, I'll say that I don't get paid for my contributions to ISO C as a member of WG14. There's no benefit to me other than public recognition. I'll also disclose the exact quantity that I've been paid for maintaining the Linux man-pages project:
You can have a conflict of interest in responsibliity without money being involved. In fact, I have never believed you were influenced by money, just that you let your personal opinions unduly influence your decisions in modifying man-pages, even when consensus seems against it.
Quoted 9 lines
110 kUSD in 2025 (from 5 sponsors) 75 kUSD in 2026 (from 3 sponsors)I'm convinced that that doesn't have any effects in my decisions here, as I've had a consistent record of decisions well before I had any economic benefits from maintaining this project. None of those sponsors have expressed any interest in favour of these decisions (nor against).
Quoted 11 lines
I'll rumiate a bit more on these patches, and probably make minor changes to them, but the essence of documenting <
memory.h> for all of mem*() and strn*() in SYNOPSIS is most likely to be eventually merged. I'll be careful to document what the standards say in a way that isn't confusing to users, and also in general will try to document it in a way that is positive for our audience --even if some of that audience may have knee-jerk reactions, like you are having at the moment--. I have also received very positive feedback for other changes for which some people have noisily had knee-jerk reactions. I believe it is my duty as maintainer of this project to do this change.
Please stop saying I'm having a kneejerk reaction. I haven't even yet commented on the substance of the changes, I've just commented on how I don't believe in making changes through man-pages like this.
Quoted 3 lines
Have a lovely day!
Alex
sam
Re: [PATCH 1/2] man/man3/{mem,strn}*(): SYNOPSIS, STANDARDS: Document these as provided by <memory.h>
In reply to Alejandro ColomarQuoted 25 lines · Alejandro Colomar
Hi Sam,
Quoted 14 lines
Date: 2026-07-31 22:54:27+0100
From: Sam James <[email protected]>Quoted 9 lines · Alejandro Colomar
Hi Joseph,
Quoted 7 lines
Date: 2026-07-31 21:23:35+0000
From: Joseph Myers <[email protected]>I think it's irresponsible to use the man-pages project to promote personal idiosyncratic ideas like this in preference to what's been the standard location of functions since 1989.
Quoted 8 lines
Quoted 4 lines
Quoted 1 line
I'd rather we add a mandatory deprecation warning to
memory.hin glibc.I hope you don't; it'd be a gratuitous breaking change.
Yet this change has the same effect, just people will see it themselves rather than the compiler telling them, and go around sending patches to change it.
Quoted 8 lines
IME, people don't go changing includes unless they need something it's not available in the already-included header files.
Analysis of includes is quite complex, and there are tools for that --iwyu(1)--. As long as those tools don't start complaining --and they won't-- [1], I find it quite unlikely that people will start changing includes in existing code.
OK, that's useful behaviour. I wasn't aware it accepted a list of headers that would provide it.
Quoted 7 lines
This is rather something that will affect new code (new source files).
[1] iwyu(1) works in a way that it allows a number of headers to
provide a symbol. If no header provides the symbol, then it will recommend the best header for it; but if a header that provides the symbol is already there, it won't complain.
Quoted 6 lines
Quoted 2 lines
The man pages should reflect what the standard currently says, not what you'd like it to say.
Not exactly; the standard is a good guideline, but sometimes it's off. We have vendor extensions, which are well documented, and when the standard is bogus, the extensions take over the page.
I think we have different views on the purpose of man-pages and users' expectations of them.
Quoted 17 lines
FWIW, the information from the standard is still there.
$ MANWIDTH=64 mansectf STANDARDS man3/memcpy.3 | cat memcpy(3) Library Functions Manual memcpy(3)STANDARDS
C11, POSIX.1‐2008.ISO C and POSIX declare this function in <
string.h>.Linux man‐pages (unreleased) (date) memcpy(3)
I've just removed it from the front of the page (SYNOPSIS), but it's still there, because of course, we must document the standard alongside the extension.
Quoted 7 lines
Quoted 2 lines
We had the same problem with e.g. stripping "C89"
everywhere.Sorry for that one; it was a useful change, though. Now we have better manual pages than we had back then, regarding standards. I hope you realize about that. It triggered discussion, and a careful review of the text, which resulted in a good change after all.
Yes, we got there in the end, but it was very disruptive, and caused a lot of pain. I am not sure the right lessons have been learned from it.
Quoted 8 lines
Quoted 2 lines
People want it to reflect what the standard says.
And it still does.
Have a lovely night!
Alex
Re: on the irresponsibility of pursuing C language reform
In reply to G. Branden RobinsonQuoted 1 line · G. Branden Robinson
Hi Sam,
Hi Branden,
Quoted 31 lines
Quoted 10 lines · Sam James
Quoted 9 lines · G. Branden Robinson
Quoted 3 lines · Joseph Myers
I think it's irresponsible to use the man-pages project to promote personal idiosyncratic ideas like this in preference to what's been the standard location of functions since 1989.
I'm sure I don't need to bring to your attention what a mine field string/
charsequence/memory buffer handling has been in C since the language's inception.Quoted 8 lines
Quoted 5 lines
More to the point: what's a better forum for pursuing this attempt at reform that will both (a) reach a significant population of stakeholders who can variously red-team it and/or endorse it; and (b) has sufficient visibility that it can't easily be ignored by people who oppose reform in this area for whatever reason?
I think the man page already tries to discourage use in its CAVEATS section.
Yes, but that's not a language reform, which is what Alex is pursuing with "alx-0097r1". In at least one earlier iteration he's expressed his intention to submit an N document to WG14.
Quoted 6 lines
Quoted 5 lines
I hope you do not wish to imply that a closed session of some committee, or unofficial backroom politicking would be preferable, nor that WG14 should close its doors to members of its user community who have not been vetted for a disinclination to boat-rocking.
Quoted 6 lines
Quoted 2 lines
I am confused as to where that implication could have possibly come from.
From familiarity with Alex's stated objective and rationale, which we can acquire from the recent list traffic Joseph characterized as irresponsible.
Ah, I see. Thanks for explaining.
To clarify then: I have no issue with Alex advocating changes. I just have an issue with man-pages being used regularly as a vehicle for that.
Quoted 12 lines
AC> The C Committee is discussing standardization of <
memory.h>, so AC> let's give it a bump.AC> I'll send you a copy of a paper I'm writing for the C Committee.
AC> It is at the bottom of this email. I will publish it as an N AC> document in August.
https://lore.kernel.org/linux-man/784288e704183a4297aeaa3d13af8edab18bc1ea.1785532392.git.alx@kernel.org/
https://lore.kernel.org/linux-man/amaTpQxd52iYjlor@devuan/
Quoted 8 lines
Quoted 3 lines
Joseph is opposing the change in the form of a patch that is likely to be applied (*) to man-pages.git which has the effect of advocacy.
Yes, and he said so categorically. More constructive advice might have taken the form of recommending a sequencing for staged changes. Here's a crude sketch.
I agree this is more productive, thanks for setting it out.
Quoted 13 lines
1. Expand "CAVEATS" sections in relevant Linux man-pages documents. 2. Pursue N-document work with WG14. 3. When WG14 has disposed of that N-document (and any descendantsthereof), update Linux man-pages documents as appropriate.
Joseph's almost certainly better placed than I to add a "step 1.5" such that Alex might pursue some course that would better prepare the ground for his step 2. I haven't attempted revision of the C language standard myself, so I can't offer specific advice regarding how best to pursue such an objective. I possess only notions of elemental principles regarding how democratic, consultative bodies of technical experts _should_ serve the public.
Quoted 7 lines
That _is_ what we're here for, right?
Quoted 2 lines
I don't think it has anything to do with WG14 membership or anything of the like? What am I missing?
See above regarding Alex's publicly circulated drafts and expressed plans.
What I mean is that I didn't take Joseph's comments to be an objection to Alex's WG14 membership or anything of the sort, just that man-pages isn't an appropriate vehicle for it. In any case, that's my position even if I misunderstood Joseph's.
Quoted 5 lines
Quoted 4 lines
(*) Alex has a history of making opinonated changes like this to
man-pages, such as removing references to older standards, and using a somewhat novel (to many) syntax for prototypes.
Quoted 7 lines
I concur with that assessment. However, a person having a history of making opinionated changes is not sound grounds for evaluation of a technical proposal, especially if it's topically unrelated.
Preoccupying oneself with irrelevancies distracts from the conscientious execution of standards committee participation.
Thanks for your thoughtful email. I found it helpful!
Quoted 2 lines
Regards,
Branden
sam
Alejandro Colomar
maintainerRe: on the irresponsibility of pursuing C language reform
In reply to Sam JamesHi Sam,
Quoted 3 lines
Date: 2026-08-01 15:38:42+0100
From: Sam James <[email protected]>
[...]
Quoted 7 lines
Quoted 5 lines
I'd say I have a history of making changes based on thorough revision of history and technical merits, even when that research is contrary to decades (or half-centuries) of common practice, and possibly to current or withdrawn standards.
The primary issue I have is that I don't often see you change your mind
I do quite frequently, actually. Most recently, this week:
<https://lore.kernel.org/linux-man/CAMdZqKEEncWS64BUL1qa0SfcNUaNA9XRBPWTpHPB==N3VV_Nzg@mail.gmail.com/>
<https://lore.kernel.org/linux-man/amupqzN_X57Du4AJ@devuan/>
> Date: Thu, 30 Jul 2026 21:51:16 +0200 > From: Alejandro Colomar <[email protected]> > > > Date: Thu, 30 Jul 2026 10:58:26 -0700 > > From: Mark Harris <[email protected]> > > > > It seems like you've already made up your mind that memccpy() > > is bad and are now just looking to justify that decision. > > Not necessarily. I can be convinced with good arguments. :-) > ... > Agreed; there are use cases where memccpy(3) is preferrable. > You've convinced me. :)
There are many other cases about cases where I had a strong opinion, and people that are currently in CC have changed my mind.
Even you've changed my mind a few times, even if you don't remember or didn't realize.
Quoted 2 lines
or acknowledge that being the man-pages maintainer is a privileged position,
It's certainly a privileged position. Just like maintainer of GCC, or of Clang, or any other core project of most systems. I acknowledge this, and I believe I've acknowledged this before, implicitly and explicitly.
Quoted 1 line
or separate your desires from the maintainership role.
My only desires are making it easy to allow programmers to write good programs. I believe that's my main responsibility as maintainer of this project, and in general, the task of any good documentation.
Quoted 3 lines
When I'm acting in a maintainer role, I often take changes I don't particularly agree with if they're technically sound and there's broad consensus for them. I think many do.
I also do often (and you probably don't notice, because you're not part of this project, and are not here to observe every change). But sometimes, I must make decisions that some people --no matter how important-- may disagree with. I might be wrong, and I'll certainly re-think about them after-the-fact, but this is one of them.
Quoted 7 lines
Quoted 5 lines
In this case, and I don't mean this specific patch set, but the years- long revision of string documentation that I've been carrying out, we have a conflict between the design and correct use of string and memory functions, and their common use today.
Yes, I don't dispute that the terminology is poor.
It's not only a matter of terminology. And in fact, I thing the terminology could be acceptable (not ideal, though).
Quoted 8 lines
Quoted 8 lines
The functions that are most subject to this conflict are strncpy(3), strncat(3), and memccpy(3). But the rest of strn*() are also somewhat affected, and the rest of mem*() minorly affected.
They were originally designed for a specific use case for which they were great. This knowledge has been lost in time, and I've been working to recover that knowledge.
Quoted 8 lines
Quoted 5 lines
Precisely because of standards and other documentation that isn't written with the level of care that I have, we have decades of misuses of strncpy(3) and strncat(3).
Moreover, it's in other places that you should be complaining about.
I do complain about those, and we finally got some consensus on the GCC side on not warning about a bunch of them by default, even.
What do you mean? And why have I not been CCed in such discussions, after being the original reporter of the problems? That kind of issue management is certainly worse than what we're discussing here.
I believe that even though I may disagree with others, it's good to hear their opinions, no matter how convinced I am that they're wrong, and no matter how much they'll blame me for taking bad decisions. Feedback is (almost) always good, even when it's negative.
What exact changes have consensus in GCC? How can there be consensus if you haven't CCed the relevant people (including me)?
In any case, I guess it's good if GCC will improve.
Quoted 11 lines
Quoted 11 lines
GCC has a bogus set of diagnostics about strncpy(3) and strncat(3), which we could very well call opinionated, and I haven't seen anyone reporting them as bogus before I did. Those diagnostics have not been considered opinionated, just because they follow mainstream (bogus) usage of these functions, but they are indeed forcing an opinion of how these functions should be used over other uses that may be more uncommon but which are actually the original and correct uses of these functions.
<https://inbox.sourceware.org/gcc/[email protected]/>
<https://gcc.gnu.org/bugzilla/show_bug.cgi?id=123024>
<https://gcc.gnu.org/bugzilla/show_bug.cgi?id=122963>
Quoted 6 lines
Quoted 4 lines
It's curious that you called the GCC diagnostic "heuristics" instead of "opinionated". There's nothing about heuristics there. It's just an enforcement of an (incorrect) opinion about how these functions should be used.
The warnings are both opinionated
Thanks!
Quoted 3 lines
and heuristics-based. I'm not sure how
you could read the comment you linked to as somehow an endorsement of the status quo,
I don't read it as an endorsement of the status-quo. Just a diminishing of the fact that GCC maintainers, just like every other project, have opinions --sometimes, like here, wrong opinions--, and they affect other programmers that try to write good code.
Quoted 1 line
I've been quite vocal about changing it elsewhere too?
I'm not aware of anything that has not me in CC; sorry.
Quoted 33 lines
Quoted 33 lines
And since C23, we're seeing that the same story is repeating with memccpy(3), which was once a niche function that was great for implementing fgets(3), and now is misused by everyone and their dog for copying strings with truncation.
I have spent probably more time than anyone in the last 5 years researching about string handling, and have proven the correctness of my research in the shadow-utils project, where most of my work has been in revising string and memory handling code. I've fixed uncountable subtle bugs in such code, and have made the resulting code actually readable. And the number of accidental regressions is minimal (IIRC, one or two regressions related to string and memory handling, in all that time, and not too dangerous).
Thus, I think it is my responsibility, as maintainer of the documentation project most read by C programmers, to let our audience learn what I've learnt in these years, and allow them to write safe string- and memory-handling code.
It is thanks to this years-long research that I've been able to gather important knowledge from people like Mark Harris, Doug McIlroy, Branden, and many others, who hold knowledge that few other programmers possess, and spread it to the world.
I'd consider it a negligence to do the easy thing and follow what standards say, or what most programmers do, because that's what has led us to the well-known mistakes that C programmers make.
FWIW, regarding the possible conflict of interest that was mentioned yesterday, I'll say that I don't get paid for my contributions to ISO C as a member of WG14. There's no benefit to me other than public recognition. I'll also disclose the exact quantity that I've been paid for maintaining the Linux man-pages project:
[...]
Quoted 2 lines
In fact, I have never believed you were influenced by money,
Thanks!
Quoted 2 lines
just that you let your personal opinions unduly influence your decisions in modifying man-pages,
I've done a lot of research and hearing experts to reach this decision(s). I believe it's not just an opinion, but a technical decision even if a controversial one.
[reordered]
Quoted 2 lines
You can have a conflict of interest in responsibliity without money being involved.
I'll continue to think about this and other concerns, and may change my mind later. At this moment, I believe I'm taking a technical decision after hearing enough experts and researching the topic more than anyone for several years.
Quoted 1 line
even when consensus seems against it.
I wouldn't say consensus against; just a vocal number of people that disagree. I wouldn't say there's consensus in favour, of course, but when there's no consensus, I have to take the last decision. Most of the time, that last decision means not doing anything, but in this case, it's different.
Cheers,
Alex
Signature · 1 line
<https://www.alejandro-colomar.es>
Alejandro Colomar
maintainerRe: [PATCH 1/2] man/man3/{mem,strn}*(): SYNOPSIS, STANDARDS: Document these as provided by <memory.h>)
In reply to Christopher BazleyHi Chris,
Quoted 22 lines
Date: 2026-08-01 15:26:05+0100
From: Christopher Bazley <[email protected]>Quoted 11 lines · G. Branden Robinson
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.hstring.hstdstrn.hwould 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.
Quoted 7 lines
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).
Quoted 8 lines
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.
Quoted 2 lines
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.
Quoted 1 line
Christopher
Have a lovely day!
Alex
Signature · 1 line
<https://www.alejandro-colomar.es>
Re: on the irresponsibility of pursuing C language reform
In reply to Alejandro ColomarQuoted 12 lines · Alejandro Colomar
Hi Sam,
Quoted 3 lines
Date: 2026-08-01 15:38:42+0100
From: Sam James <[email protected]>[...]
Quoted 6 lines
Quoted 5 lines
I'd say I have a history of making changes based on thorough revision of history and technical merits, even when that research is contrary to decades (or half-centuries) of common practice, and possibly to current or withdrawn standards.
Quoted 6 lines
Quoted 1 line
The primary issue I have is that I don't often see you change your mind
I do quite frequently, actually. Most recently, this week:
<https://lore.kernel.org/linux-man/CAMdZqKEEncWS64BUL1qa0SfcNUaNA9XRBPWTpHPB==N3VV_Nzg@mail.gmail.com/>
<https://lore.kernel.org/linux-man/amupqzN_X57Du4AJ@devuan/>
OK, I don't frequently see you change your mind on any of these big contentious threads we have every so often.
Quoted 16 lines
> Date: Thu, 30 Jul 2026 21:51:16 +0200 > From: Alejandro Colomar <[email protected]> > > > Date: Thu, 30 Jul 2026 10:58:26 -0700 > > From: Mark Harris <[email protected]> > > > > It seems like you've already made up your mind that memccpy() > > is bad and are now just looking to justify that decision. > > Not necessarily. I can be convinced with good arguments. :-) > ... > Agreed; there are use cases where memccpy(3) is preferrable. > You've convinced me. :)
Quoted 5 lines
There are many other cases about cases where I had a strong opinion, and people that are currently in CC have changed my mind.
Even you've changed my mind a few times, even if you don't remember or didn't realize.
OK.
Quoted 9 lines
Quoted 3 lines
or acknowledge that being the man-pages maintainer is a privileged position,
It's certainly a privileged position. Just like maintainer of GCC, or of Clang, or any other core project of most systems. I acknowledge this, and I believe I've acknowledged this before, implicitly and explicitly.
Quoted 5 lines
Quoted 1 line
or separate your desires from the maintainership role.
My only desires are making it easy to allow programmers to write good programs. I believe that's my main responsibility as maintainer of this project, and in general, the task of any good documentation.
I think the previous man-pages maintainer behaved differently and people have come to expect that style of management over the years.
Quoted 11 lines
Quoted 4 lines
When I'm acting in a maintainer role, I often take changes I don't particularly agree with if they're technically sound and there's broad consensus for them. I think many do.
I also do often (and you probably don't notice, because you're not part of this project, and are not here to observe every change). But sometimes, I must make decisions that some people --no matter how important-- may disagree with. I might be wrong, and I'll certainly re-think about them after-the-fact, but this is one of them.
I'm saying that you seem to be in the position of making such changes more than many.
Quoted 11 lines
Quoted 7 lines
Quoted 5 lines
In this case, and I don't mean this specific patch set, but the years- long revision of string documentation that I've been carrying out, we have a conflict between the design and correct use of string and memory functions, and their common use today.
Yes, I don't dispute that the terminology is poor.
It's not only a matter of terminology. And in fact, I thing the terminology could be acceptable (not ideal, though).
OK, I'm saying I don't disagree that strings vs memory is a mess in C.
Quoted 12 lines
Quoted 12 lines
Quoted 12 lines
The functions that are most subject to this conflict are strncpy(3), strncat(3), and memccpy(3). But the rest of strn*() are also somewhat affected, and the rest of mem*() minorly affected.
They were originally designed for a specific use case for which they were great. This knowledge has been lost in time, and I've been working to recover that knowledge.
Precisely because of standards and other documentation that isn't written with the level of care that I have, we have decades of misuses of strncpy(3) and strncat(3).
Quoted 9 lines
Quoted 4 lines
Quoted 1 line
Moreover, it's in other places that you should be complaining about.
I do complain about those, and we finally got some consensus on the GCC side on not warning about a bunch of them by default, even.
What do you mean? And why have I not been CCed in such discussions, after being the original reporter of the problems? That kind of issue management is certainly worse than what we're discussing here.
???
First, it wouldn't make sense to CC every reporter of such a bug involving middle-end warnings on such a thread.
Second, there have been several such discussions on the ML and at the GNU Cauldron, the most recent one I'm referring to being
https://inbox.sourceware.org/gcc/CAH6eHdRfEVsGjbJ__kU5AR9BfVdLQZ_iGGDZa=yQnT4fgG2P6w@mail.gmail.com/.
There have been (many) others regarding both the FP nature of the warnings and also growing consensus on IRC and the MLs when these issues come up that some of them are too opinionated in addition to being heuristics-based. Some of them are based on style that shouldn't really be in the warnings (or at least not on by default if so), and some of it is inherently prone to false-positives, some both.
Quoted 8 lines
I believe that even though I may disagree with others, it's good to hear their opinions, no matter how convinced I am that they're wrong, and no matter how much they'll blame me for taking bad decisions. Feedback is (almost) always good, even when it's negative.
What exact changes have consensus in GCC? How can there be consensus if you haven't CCed the relevant people (including me)?
See above.
Quoted 26 lines
In any case, I guess it's good if GCC will improve.
Quoted 11 lines
Quoted 11 lines
GCC has a bogus set of diagnostics about strncpy(3) and strncat(3), which we could very well call opinionated, and I haven't seen anyone reporting them as bogus before I did. Those diagnostics have not been considered opinionated, just because they follow mainstream (bogus) usage of these functions, but they are indeed forcing an opinion of how these functions should be used over other uses that may be more uncommon but which are actually the original and correct uses of these functions.
<https://inbox.sourceware.org/gcc/[email protected]/>
<https://gcc.gnu.org/bugzilla/show_bug.cgi?id=123024>
<https://gcc.gnu.org/bugzilla/show_bug.cgi?id=122963>Quoted 6 lines
Quoted 4 lines
It's curious that you called the GCC diagnostic "heuristics" instead of "opinionated". There's nothing about heuristics there. It's just an enforcement of an (incorrect) opinion about how these functions should be used.
The warnings are both opinionated
Thanks!
Quoted 3 lines
and heuristics-based. I'm not sure how
you could read the comment you linked to as somehow an endorsement of the status quo,
Quoted 8 lines
I don't read it as an endorsement of the status-quo. Just a diminishing of the fact that GCC maintainers, just like every other project, have opinions --sometimes, like here, wrong opinions--, and they affect other programmers that try to write good code.
Quoted 1 line
I've been quite vocal about changing it elsewhere too?
I'm not aware of anything that has not me in CC; sorry.
I wasn't in CC yet I came across this thread. Should you have CCed me?
(No, I don't believe you should have; this is what mailing lists are for.)
Quoted 56 lines
Quoted 34 lines
Quoted 34 lines
And since C23, we're seeing that the same story is repeating with memccpy(3), which was once a niche function that was great for implementing fgets(3), and now is misused by everyone and their dog for copying strings with truncation.
I have spent probably more time than anyone in the last 5 years researching about string handling, and have proven the correctness of my research in the shadow-utils project, where most of my work has been in revising string and memory handling code. I've fixed uncountable subtle bugs in such code, and have made the resulting code actually readable. And the number of accidental regressions is minimal (IIRC, one or two regressions related to string and memory handling, in all that time, and not too dangerous).
Thus, I think it is my responsibility, as maintainer of the documentation project most read by C programmers, to let our audience learn what I've learnt in these years, and allow them to write safe string- and memory-handling code.
It is thanks to this years-long research that I've been able to gather important knowledge from people like Mark Harris, Doug McIlroy, Branden, and many others, who hold knowledge that few other programmers possess, and spread it to the world.
I'd consider it a negligence to do the easy thing and follow what standards say, or what most programmers do, because that's what has led us to the well-known mistakes that C programmers make.
FWIW, regarding the possible conflict of interest that was mentioned yesterday, I'll say that I don't get paid for my contributions to ISO C as a member of WG14. There's no benefit to me other than public recognition. I'll also disclose the exact quantity that I've been paid for maintaining the Linux man-pages project:
[...]
Quoted 2 lines
In fact, I have never believed you were influenced by money,
Thanks!
Quoted 2 lines
just that you let your personal opinions unduly influence your decisions in modifying man-pages,
I've done a lot of research and hearing experts to reach this decision(s). I believe it's not just an opinion, but a technical decision even if a controversial one.
[reordered]
Quoted 2 lines
You can have a conflict of interest in responsibliity without money being involved.
I'll continue to think about this and other concerns, and may change my mind later. At this moment, I believe I'm taking a technical decision after hearing enough experts and researching the topic more than anyone for several years.
Quoted 7 lines
Quoted 1 line
even when consensus seems against it.
I wouldn't say consensus against; just a vocal number of people that disagree. I wouldn't say there's consensus in favour, of course, but when there's no consensus, I have to take the last decision. Most of the time, that last decision means not doing anything, but in this case, it's different.
What would real consensus against look like?
Quoted 4 lines
Cheers,
Alex
Alejandro Colomar
maintainerRe: on the irresponsibility of pursuing C language reform
Hi Sam,
Quoted 3 lines
Date: 2026-08-01 17:10:30+0100
From: Sam James <[email protected]>
[...]
Quoted 3 lines
I think the previous man-pages maintainer behaved differently and people have come to expect that style of management over the years.
I know Michael, and still have regular contact with him. We have a sligthly different management style in some topics, indeed. Not saying any of them is better or worse, though.
[...]
Quoted 8 lines
Quoted 7 lines
Quoted 2 lines
I do complain about those, and we finally got some consensus on the GCC side on not warning about a bunch of them by default, even.
What do you mean? And why have I not been CCed in such discussions, after being the original reporter of the problems? That kind of issue management is certainly worse than what we're discussing here.
Quoted 4 lines
???
First, it wouldn't make sense to CC every reporter of such a bug involving middle-end warnings on such a thread.
I'm not a random one-time reporter.
Quoted 3 lines
Second, there have been several such discussions on the ML and at the GNU Cauldron, the most recent one I'm referring to being
https://inbox.sourceware.org/gcc/CAH6eHdRfEVsGjbJ__kU5AR9BfVdLQZ_iGGDZa=yQnT4fgG2P6w@mail.gmail.com/.
I'm not subscribed to gcc's mailing list.
Quoted 6 lines
There have been (many) others regarding both the FP nature of the warnings and also growing consensus on IRC and the MLs when these issues come up that some of them are too opinionated in addition to being heuristics-based. Some of them are based on style that shouldn't really be in the warnings (or at least not on by default if so), and some of it is inherently prone to false-positives, some both.
Attributing those diagnostics to style is wrong. They are based on an incorrect understanding of these functions. Style is whether to add spaces after a function identifier or not.
It's not a matter of false-positives either. The entire diagnostic is *always* unconditionally wrong.
Quoted 42 lines
Quoted 8 lines
I believe that even though I may disagree with others, it's good to hear their opinions, no matter how convinced I am that they're wrong, and no matter how much they'll blame me for taking bad decisions. Feedback is (almost) always good, even when it's negative.
What exact changes have consensus in GCC? How can there be consensus if you haven't CCed the relevant people (including me)?
See above.
Quoted 31 lines
In any case, I guess it's good if GCC will improve.
Quoted 11 lines
Quoted 11 lines
GCC has a bogus set of diagnostics about strncpy(3) and strncat(3), which we could very well call opinionated, and I haven't seen anyone reporting them as bogus before I did. Those diagnostics have not been considered opinionated, just because they follow mainstream (bogus) usage of these functions, but they are indeed forcing an opinion of how these functions should be used over other uses that may be more uncommon but which are actually the original and correct uses of these functions.
<https://inbox.sourceware.org/gcc/[email protected]/>
<https://gcc.gnu.org/bugzilla/show_bug.cgi?id=123024>
<https://gcc.gnu.org/bugzilla/show_bug.cgi?id=122963>Quoted 6 lines
Quoted 4 lines
It's curious that you called the GCC diagnostic "heuristics" instead of "opinionated". There's nothing about heuristics there. It's just an enforcement of an (incorrect) opinion about how these functions should be used.
The warnings are both opinionated
Thanks!
Quoted 3 lines
and heuristics-based. I'm not sure how
you could read the comment you linked to as somehow an endorsement of the status quo,I don't read it as an endorsement of the status-quo. Just a diminishing of the fact that GCC maintainers, just like every other project, have opinions --sometimes, like here, wrong opinions--, and they affect other programmers that try to write good code.
Quoted 5 lines
Quoted 3 lines
Quoted 1 line
I've been quite vocal about changing it elsewhere too?
I'm not aware of anything that has not me in CC; sorry.
I wasn't in CC yet I came across this thread. Should you have CCed me?
I did indeed CC bug-gnulib@ and libc-alpha@. I could have kept the discussion in linux-man@, if I wasn't interested in hearing from you and other people who are likely to be interested in being aware and sharing their opinions.
And that's also why I CCed Joseph and other people explicitly, as they have expressed opinions about this topic in previous discussions.
I think this is a good guideline:
Please CC any relevant developers and mailing lists that may know about or be interested in the discussion. If your email discusses a feature or change, and you know which developers added the feature or made the change that your email discusses, please CC them on the email; with luck they may review and comment on it. If you don't know who the developers are, you may be able to discover that information from mailing list archives or from git(1) logs or logs in other version control systems. Obviously, if you are the developer of the feature being discussed in a man-pages email, please identify yourself as such. Relevant mailing lists may include:
Quoted 2 lines
(No, I don't believe you should have; this is what mailing lists are for.)
I disagree. But that might be a difference in project conventions. The guidelines we use here, which come from Michael, and are similar to the kernel's ones, are to CC people explicitly when they might be interested. I'm aware that GCC has a different tradition in this regard, though.
[...]
Quoted 10 lines
Quoted 10 lines
Quoted 2 lines
You can have a conflict of interest in responsibliity without money being involved.
I'll continue to think about this and other concerns, and may change my mind later. At this moment, I believe I'm taking a technical decision after hearing enough experts and researching the topic more than anyone for several years.
Quoted 1 line
even when consensus seems against it.
Quoted 7 lines
Quoted 5 lines
I wouldn't say consensus against; just a vocal number of people that disagree. I wouldn't say there's consensus in favour, of course, but when there's no consensus, I have to take the last decision. Most of the time, that last decision means not doing anything, but in this case, it's different.
What would real consensus against look like?
Well, Keith Bostic wouldn't have suggested that I do this change, and Branden wouldn't be defending that it might make sense to make this change.
A vocal majority is not consensus. Consensus would be if there were no significantly different or strongly opposed opinions to those of the majority. Even my strong and sustained opposition against your opinion already means there's no consensus against.
Cheers,
Alex
Signature · 1 line
<https://www.alejandro-colomar.es>
Re: 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>)
In reply to Douglas McIlroyHi Doug,
Quoted 7 lines · Douglas McIlroy
Branden wrote
Quoted 3 lines
I'm sure I don't need to bring to your attention what a mine field string/
charsequence/memory buffer handling has been in C since the language's inception.Yes, this is a property of the language, not a peculiar deficiency of the <
string.h> functions.
I mostly agree. I think it's possible that C's string interfaces managed to innovate some deficiencies of their own on top of those proferred by the underlying the language definition. 8-O
Quoted 2 lines
As I see it, patching up perceived deficiencies of the functions adds complexity to the language definition and to the task of code-reading,
That's true. But it is also true that without clear guidance from the standard's specification of the library, and with the flagship text on the language having gone unrevised since 1988, those perceived deficiencies cause ad hoc innovations to sprout like mushrooms after a thunderstorm. Some of those innovations, like OpenBSD's strlcat and strlcpy (1998), claw their way into acceptance. Others don't, and remain bespoke features of a particular code project--often with little commentary or accompanying documentation to illuminate them.
The result? Reading _any_ code that involves string/char sequence/ memory buffer handling has a substantial complexity tax stuck onto it.
Culturally, it used to be that any inadequacies of the C language or its standard library were hand-waved away because a coder of sufficient ability could bull through any challenge with cleverness. Our community has been purged of that preening vanity ten thousand CVEs at a time.
I think one of the reasons Alex is getting pushback is that everybody knows this is a horrible can of worms--Joseph referred to "relitigation" --and that in turn is because seasoned C practitioners have a shared dread that instead of a brilliant solution existing somewhere in library design space, we face only struggles over who the taxing authorities shall be. And everybody hates the tax man.
Quoted 1 line
with little real benefit.
If there is no Pareto improvement available in any dimension, but just reshuffling of code-reading tax authorities, then you're right.
I can, at best, hope the situation is not that bad.
If it is, what is to be done?
Regards,
Branden
Re: on the irresponsibility of pursuing C language reform
In reply to Sam JamesHi Sam & Alex,
Just a quick note on conflicts on interest since I'm the one who dragged that label into the conversation--though the concept was implicitly present already.
Quoted 10 lines · Sam James
Quoted 5 lines · Alejandro Colomar
FWIW, regarding the possible conflict of interest that was mentioned yesterday, I'll say that I don't get paid for my contributions to ISO C as a member of WG14. There's no benefit to me other than public recognition. I'll also disclose the exact quantity that I've been paid for maintaining the Linux man-pages project:
You can have a conflict of interest in responsibliity without money being involved. In fact, I have never believed you were influenced by money,
Sam makes a good point, and Alex, I think you overlooked one.
Disclosure of the quantity of your compensation as Linux man-pages maintainer is of less importance than _who_ sponsored your work.
When we're speaking of currency, yes, quantity eventually has a quality all its own. But knowing who's been signing the checks is almost always the more valuable information because it tells us who is in a position to expect favorable treatment. Sometimes that's because the parties negotiate a quid pro quo, but more often sponsors can count on "self-regulation" by their beneficiaries. Money men understand that people's minds and uncritical loyalties can often be bought cheaply.
Free your mind and something else will follow, I think someone said.
Here's a backgrounder that's less antiseptic than a corporate ethics slide deck training module on conflicts of interest.
https://www.propublica.org/article/clarence-thomas-money-complaints-sparked-resignation-fears-scotus
Regards,
Branden
Alejandro Colomar
maintainerRe: 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>)
In reply to G. Branden RobinsonHi Branden, Doug,
Quoted 13 lines
Date: 2026-08-01 14:54:35-0500
From: "G. Branden Robinson" <[email protected]>Hi Doug,
Quoted 7 lines · Douglas McIlroy
Branden wrote
Quoted 3 lines
I'm sure I don't need to bring to your attention what a mine field string/
charsequence/memory buffer handling has been in C since the language's inception.Yes, this is a property of the language, not a peculiar deficiency of the <
string.h> functions.
Actually, I'm going to disagree on the first principle: the language is not flawed, and <string.h> functions aren't particularly bad either.
The fact that they can be used safely after you understand the tools means that the tools are good. It's the teaching that has been bad.
Just like with every sharp tool, you need to first understand the tool.
After 5 years of researching about <string.h> functions, I've proved with example that one can rewrite vast amounts of string code without regressions every two lines of code. This can only mean that <string.h> is not inherently dangerous, since I'm not especially free from the human-mistake factor (actually, I feel I'm more prone to them than the average programmer).
<string.h> lacks a few functions and macros that make life much simpler, such as Linux's strscpy(9), gnulib's streq(3), and a few others.
That lack, I attribute it to the fact that programmers have been burnt so many times on bad design that they have grown an aversion to adding them. The fiasco of Annex K has probably helped.
Quoted 6 lines
I mostly agree. I think it's possible that C's string interfaces managed to innovate some deficiencies of their own on top of those proferred by the underlying the language definition. 8-O
Quoted 2 lines
As I see it, patching up perceived deficiencies of the functions adds complexity to the language definition and to the task of code-reading,
I'm currently just proposing a documentation change (there's another proposal I'm working on in parallel, which actually affects the functions, but that's not what we're discussing now). The functions are virtually moved to a different header file, but nothing else changes.
That header file division will help with the teaching problem, which is the problem that has affected <string.h> so badly for so long.
Quoted 6 lines
That's true. But it is also true that without clear guidance from the standard's specification of the library, and with the flagship text on the language having gone unrevised since 1988, those perceived deficiencies cause ad hoc innovations to sprout like mushrooms after a thunderstorm. Some of those innovations, like OpenBSD's strlcat and strlcpy (1998), claw their way into acceptance.
And interestingly, OpenBSD's strlcpy/cat(3) suffer from DoS, which Linux's strscpy(9) is free of.
Quoted 3 lines
Others don't, and
remain bespoke features of a particular code project--often with little commentary or accompanying documentation to illuminate them.
Indeed.
Quoted 2 lines
The result? Reading _any_ code that involves string/
charsequence/ memory buffer handling has a substantial complexity tax stuck onto it.
And indeed.
Quoted 4 lines
Culturally, it used to be that any inadequacies of the C language or its standard library were hand-waved away because a coder of sufficient ability could bull through any challenge with cleverness. Our community has been purged of that preening vanity ten thousand CVEs at a time.
And indeed.
Quoted 2 lines
I think one of the reasons Alex is getting pushback is that everybody knows this is a horrible can of worms
I'd say they think they know. I believe it's not a can of worms, if you are strict about keeping it simple.
Quoted 1 line
--Joseph referred to "relitigation"
And because the C Committee has the bad habit of considering past decisions of the committee as godspell, no matter how bad they prove to be. I've been repeatedly accused of relitigating realloc(p,0), <string.h>, and many more bad decisions of ISO C.
One good news is that Microsoft is currently testing my proposed changes to fix realloc(p,0), and when their testing is done, all the FUD that we've been hearing that it can't be changed now because "it would break the world" will just vanish.
Quoted 11 lines
--and that in turn is because seasoned C practitioners have a shared dread that instead of a brilliant solution existing somewhere in library design space, we face only struggles over who the taxing authorities shall be. And everybody hates the tax man.
Quoted 1 line
with little real benefit.
If there is no Pareto improvement available in any dimension, but just reshuffling of code-reading tax authorities, then you're right.
I can, at best, hope the situation is not that bad.
I am certain that the solution exists.
Quoted 1 line
If it is, what is to be done?
Have a lovely night!
Alex
Signature · 1 line
<https://www.alejandro-colomar.es>
Alejandro Colomar
maintainerRe: on the irresponsibility of pursuing C language reform
In reply to G. Branden RobinsonHi Branden,
Quoted 17 lines
Date: 2026-08-01 15:18:49-0500
From: "G. Branden Robinson" <[email protected]>Hi Sam & Alex,
Just a quick note on conflicts on interest since I'm the one who dragged that label into the conversation--though the concept was implicitly present already.
Quoted 7 lines · Sam James
Quoted 5 lines · Alejandro Colomar
FWIW, regarding the possible conflict of interest that was mentioned yesterday, I'll say that I don't get paid for my contributions to ISO C as a member of WG14. There's no benefit to me other than public recognition. I'll also disclose the exact quantity that I've been paid for maintaining the Linux man-pages project:
Quoted 8 lines
Quoted 3 lines
You can have a conflict of interest in responsibliity without money being involved. In fact, I have never believed you were influenced by money,
Sam makes a good point, and Alex, I think you overlooked one.
Disclosure of the quantity of your compensation as Linux man-pages maintainer is of less importance than _who_ sponsored your work.
That's public, and has been since the begining. It's published in the git repository:
$ cat SPONSORS Google <https://opensource.google/> Hudson River Trading <https://www.hudsonrivertrading.com/> Meta <https://www.meta.com/>
Here's the history of that file:
$ git log --pretty=reference -p -- SPONSORS 6d9ae347cfac (SPONSORS: Two sponsors didn't renew this year, 2025-10-29)
diff --git a/SPONSORS b/SPONSORS index 440fcca8b9ed..4b2f2e9011b8 100644 --- a/SPONSORS +++ b/SPONSORS @@ -1,5 +1,3 @@ -Adfinis <https://adfinis.com/> Google <https://opensource.google/> Hudson River Trading <https://www.hudsonrivertrading.com/> Meta <https://www.meta.com/> -Red Hat <https://www.redhat.com/> 7ea35690e060 (SPONSORS: Publish the sponsors of this project, 2025-01-15) diff --git a/SPONSORS b/SPONSORS new file mode 100644 index 000000000000..440fcca8b9ed --- /dev/null +++ b/SPONSORS @@ -0,0 +1,5 @@ +Adfinis <https://adfinis.com/> +Google <https://opensource.google/> +Hudson River Trading <https://www.hudsonrivertrading.com/> +Meta <https://www.meta.com/> +Red Hat <https://www.redhat.com/>
Cheers,
Alex
Signature · 1 line
<https://www.alejandro-colomar.es>
Alejandro Colomar
maintainerRe: on the irresponsibility of pursuing C language reform
Quoted 3 lines
Date: 2026-08-01 22:42:15+0200
From: Alejandro Colomar <[email protected]>
[...]
Quoted 13 lines
$ git log --pretty=reference -p -- SPONSORS 6d9ae347cfac (SPONSORS: Two sponsors didn't renew this year, 2025-10-29)diff --git a/SPONSORS b/SPONSORS index 440fcca8b9ed..4b2f2e9011b8 100644 --- a/SPONSORS +++ b/SPONSORS @@ -1,5 +1,3 @@ -Adfinis <https://adfinis.com/> Google <https://opensource.google/> Hudson River Trading <https://www.hudsonrivertrading.com/> Meta <https://www.meta.com/> -Red Hat <https://www.redhat.com/>
FWIW, the reason for those two that dropped, IMO, is that Adfinis is a small company that couldn't afford it, and Red Hat probably did to have more cash to burn in the AI oven.
Cheers,
Alex
Signature · 1 line
<https://www.alejandro-colomar.es>
Re: on the irresponsibility of pursuing C language reform
In reply to Alejandro ColomarHi Alex,
Quoted 2 lines · Alejandro Colomar
That's public, and has been since the begining. It's published in the git repository:
I knew it was there somewhere. (I see now--prominently, even!)
Quoted 4 lines
$ cat SPONSORS Google <https://opensource.google/> Hudson River Trading <https://www.hudsonrivertrading.com/> Meta <https://www.meta.com/>
I don't think many occasions call for you to quote the file contents. In your position I would simply have the URL to this file handy for any occasion where someone takes a run at my transparency.
In fact I think your approach to disclosure is near-optimal. In my view it is strongly superior to slathering acknowledgements of your sponsors on all of your emails in your capacity as Linux man-pages maintainer, which would degrade software engineering into something like NASCAR.
(There I go, alienating yet another fan community...)
Regards,
Branden
Alejandro Colomar
maintainerRe: on the irresponsibility of pursuing C language reform
Hi Branden,
Quoted 10 lines
Date: 2026-08-01 15:52:26-0500
From: "G. Branden Robinson" <[email protected]>Hi Alex,
Quoted 2 lines · Alejandro Colomar
That's public, and has been since the begining. It's published in the git repository:
I knew it was there somewhere. (I see now--prominently, even!)
:)
Quoted 7 lines
Quoted 5 lines
$ cat SPONSORS Google <https://opensource.google/> Hudson River Trading <https://www.hudsonrivertrading.com/> Meta <https://www.meta.com/>I don't think many occasions call for you to quote the file contents.
In every release, I do it. For example, see the last one:
<https://lore.kernel.org/linux-man/aekjQuAEaq1ILKAa@devuan/>
> From: Alejandro Colomar <[email protected]>
> To: [email protected]
> Cc: [email protected], [email protected] > Subject: man-pages-6.18 released
> Date: Wed, 22 Apr 2026 22:04:52 +0200 [thread overview]
> Message-ID: <aekjQuAEaq1ILKAa@devuan> (raw)
>
> Gidday!
>
> I'm proud to announce:
>
> man-pages-6.18 - manual pages for GNU+Linux
>
...
>
> Thanks to all the contributors to this release (in BCC)! > And thanks to our sponsors!
>
> $ sort --random-sort <SPONSORS;
> Meta <https://www.meta.com/>
> Hudson River Trading <https://www.hudsonrivertrading.com/>
> Google <https://opensource.google/>
Properly random-sorted, to avoid any preferences. In the actual file, they're sorted alphabetically. I haven't even asked how much money each of them pays to me, because I don't want to know. I only get the total amount through the Linux Foundation. (But FWIW, I guess the three pay the same.)
Quoted 2 lines
In your position I would simply have the URL to this file handy for any occasion where someone takes a run at my transparency.
Yup.
Quoted 1 line
In fact I think your approach to disclosure is near-optimal.
I've been thinking that I should disclose the total amount in the commit messages that update the file.
Quoted 4 lines
In my view
it is strongly superior to slathering acknowledgements of your sponsors on all of your emails in your capacity as Linux man-pages maintainer, which would degrade software engineering into something like NASCAR.
I do in the releases, but since they only happen a few times a year, I guess it's okay.
Quoted 4 lines
(There I go, alienating yet another fan community...)
Regards,
Branden
Cheers,
Alex
Signature · 1 line
<https://www.alejandro-colomar.es>
Re: on the irresponsibility of pursuing C language reform
In reply to Alejandro ColomarHi Alex,
Quoted 3 lines · Alejandro Colomar
Well, Keith Bostic wouldn't have suggested that I do this change, and Branden wouldn't be defending that it might make sense to make this change.
I'm flattered to be mentioned in the same breath as Keith Bostic!
Quoted 4 lines
A vocal majority is not consensus. Consensus would be if there were no significantly different or strongly opposed opinions to those of the majority. Even my strong and sustained opposition against your opinion already means there's no consensus against.
"Consensus" is a word that gets abused a lot, because it has multiple definitions. To some people it means "unanimity". To others, it means a majority vote with potentially many abstentions but no (or proportionally very few) negative votes. From reading WG14 minutes, I'm vaguely aware that it has a rubric for reading the straw polls they take when voting on N-papers and related motions.[1] I invite a member to cite a resource laying out their actual procedures.
I don't think I'm voicing a controversial view when I venture that Michael Kerrisk administered the Linux man-pages with a more settled view of the APIs it documents. By that, I mean that he tended to update its content with a retrospective view of matters that were no longer in contention. If some controversy brewed, he tended to omit it from "coverage" in the documentary corpus until the contention resolved.
Your approach is a little different: you're more ready to give the reader a view of live controversies and unsettled matters troubling the C community where these intersect with the topics man-pages(7) covers.
Neither approach is better. They're just different. I think Sam is right that people had many years to get used to Michael's approach. From there it's a short--but logically unsound--step to associate "familiar" with "better".
But, if you're going to document unresolved controversies, how do you avoid putting a thumb on the scale?
One way is to solicit review of that coverage for even-handedness--I do not say "neutrality". List pros and cons of competing interfaces or code idioms. If you do that job correctly, _reasonable_ partisans of the various contesting positions will find no cause to criticize. (There will sometimes be fanboys who object to the "opposition" getting any coverage at all.)
Further, with such lists you do a service to the engineer who must select a means of solving the problem confronting them. The engineer often knows that problem better than anyone else does.
Next comes a trickier bit: what if you yourself get involved, even while "wearing a different hat", in one of these live controversies?
Your first line of defense is your own ethical conscience.
Another, as I suggested earlier, is to solicit one or more volunteers to serve as "deputy maintainers". Prepare a list of man pages or sections thereof upon which you are "conflicted out", and ask the deputies to field all Linux man-pages business regarding those pages/sections while you have business regarding those interfaces before a vendor libc and/or the WG14 committee. It will likely be obvious to you what vehicle can communicate these areas of deputy maintenance--a man page!
I intuit that Michael had a hard time finding anyone to take the mantle of Linux man-pages maintainership. It's a huge job and demanded someone of your unusual resources and energy. By opening deputy positions that are limited both in scope and in time, nobody need worry that they'll be expected to eat the whole elephant. If you find such volunteers, then you'll also be spreading expertise and socializing personal investment in the success of this project. That's good management!
Finally, to return to the question of consensus: a potential point of development in Linux man-pages project governance is to _document how you measure consensus_.
We'd be unwise to determine consensus by measuring who writes the most words (hi, folks), or with the angriest tone, or who has the most impressive job title at the biggest company, or who can shut down a discussion most coldly or derail it most effectively.
So tell the members of this community how _you_ measure it. Put the burden on the critical and the concerned to find flaws in your method.
Regards,
Branden
[1] I'm not sure WG14 uses the term "motions", and I haven't seen much evidence that they use Robert's Rules of Order, with which Commonwealth people are likely not familiar, let alone non-Anglophones.
Alejandro Colomar
maintainerRe: on the irresponsibility of pursuing C language reform
Hi Branden,
Quoted 11 lines
Date: 2026-08-01 16:34:21-0500
From: "G. Branden Robinson" <[email protected]>Hi Alex,
Quoted 3 lines · Alejandro Colomar
Well, Keith Bostic wouldn't have suggested that I do this change, and Branden wouldn't be defending that it might make sense to make this change.
I'm flattered to be mentioned in the same breath as Keith Bostic!
:)
Quoted 9 lines
Quoted 4 lines
A vocal majority is not consensus. Consensus would be if there were no significantly different or strongly opposed opinions to those of the majority. Even my strong and sustained opposition against your opinion already means there's no consensus against.
"Consensus" is a word that gets abused a lot, because it has multiple definitions. To some people it means "unanimity". To others, it means a majority vote with potentially many abstentions but no (or proportionally very few) negative votes.
Indeed.
Quoted 4 lines
From reading WG14 minutes, I'm
vaguely aware that it has a rubric for reading the straw polls they take when voting on N-papers and related motions.[1] I invite a member to cite a resource laying out their actual procedures.
WG14, like WG21, has a problem. Consensus, these days, is taken as roughly a majority of votes.
With very few exceptions, here's the rule that guides consensus in straw polls during committee meetings:
// Consensus requires both // y/(y+n) >= 2/3 // n/(y+n+a) <= 1/4
Strong opposition is dismissed as long as the numbers are okay. We even have a small program that performs that calculation and which we consult.
As a consequence, this is what happens (very interesting read):
<https://isocpp.org/files/papers/P4238R0.pdf>.
A large number of NBs (national bodies), including mine, are going to vote against C++26, and as a consequence, it may be returned to WG21 for evaluation. This means we won't have C++26 if this happens.
Quoted 6 lines
I don't think I'm voicing a controversial view when I venture that Michael Kerrisk administered the Linux man-pages with a more settled view of the APIs it documents. By that, I mean that he tended to update its content with a retrospective view of matters that were no longer in contention. If some controversy brewed, he tended to omit it from "coverage" in the documentary corpus until the contention resolved.
Yup.
Quoted 3 lines
Your approach is a little different: you're more ready to give the reader a view of live controversies and unsettled matters troubling the C community where these intersect with the topics man-pages(7) covers.
Yup.
Quoted 1 line
Neither approach is better. They're just different.
Yup.
Quoted 4 lines
I think Sam is
right that people had many years to get used to Michael's approach. From there it's a short--but logically unsound--step to associate "familiar" with "better".
Yup.
Quoted 2 lines
But, if you're going to document unresolved controversies, how do you avoid putting a thumb on the scale?
Doing a lot of research. Whatever I don't research myself, I still act like Michael, and tend to not step into. But string and memory handling is something that has taken most of my time in the last 5 years or so.
Quoted 3 lines
One way is to solicit review of that coverage for even-handedness--I do not say "neutrality". List pros and cons of competing interfaces or code idioms.
I do indeed get that. Mark gave me feedback about memccpy(3) recently, which I've incorporated to my research. That was the last issue I had with <string.h>, because memccpy(3) is something I've never seen in real correct use. It seems Illumos is one of the places where they store that old knowledge. It's good that those projects still exist and can be used to learn about our history.
Sam was concerned about not docuementing what standards say; and indeed, I'll make sure to document that (in STANDARDS, where it belongs; which I had already done, BTW). Other than that, he was worried that I might be encoding an opinion, but I believe this is a technical judgement based on research, and not an opinion. So, dismissed.
Joseph was concerned that this documentation would conflict with many documents saying that <memory.h> is deprecated. Luckily, I've never seen such a document, so we can assume they don't exist (unless people show evidence). I'll dismiss his negative vote, since his technical reasons are incorrect. Also, <memory.h> is undoubtedly more portable than a new <stdmem.h>.
It's also a bit Ironic that Joseph started with a strongly opinionated
proposal: deprecating <memory.h> in glibc (breaking 8.9k uses in Debian).
Collin didn't comment, although by his support to Joseph's suggestion of deprecating <memory.h>, I guess he's against. Since he didn't provide any new reasons, I guess it's more of Joseph's. Already dismissed, then.
Nevin has an undeclared conflict of interest: He is the author of a proposal for WG14 to remove strncpy(3).
<https://www.open-std.org/jtc1/sc22/wg14/www/docs/n3935.htm>
Also, he didn't really give any technical reasons; he just voted no. A vote without reasons is still heard, but easily dismissed.
Keith suggested doing this, by which I assume he's in favour. He's certainly an expert in the topic, and I'd value his support.
I value Doug's opinion too, although he didn't show much technical reasons this time. He was mostly concerned about changing string functions, but didn't clarify whether he was concerned about restoring <memory.h>. Thus, I'd say I won't count that.
You seem to support the fact that something should be done, except that you may not entirely agree with the approach. You've been a bit misguided by Joseph's concerns about <memory.h>, so I'll dismiss that part of your feedback as being just Joseph's --which I've already dismissed on technical grounds--.
Chris is concerned about my arbitrary separation, but I think his separation is also somewhat arbitrary. I'll trust my instinct here. We're always in time to revise this. In any case, this arbitrary distinction is better than the status quo.
Thus, with support from Keith, and no sustained opposition based on technical ground (Joseph didn't contest my response that absolutely no mainstream documents talk about <memory.h> being deprecated, and himself said that it's only *implicitly* deprecated), I should commit.
Quoted 22 lines
If you do that job correctly, _reasonable_ partisans of
the various contesting positions will find no cause to criticize. (There will sometimes be fanboys who object to the "opposition" getting any coverage at all.)Further, with such lists you do a service to the engineer who must select a means of solving the problem confronting them. The engineer often knows that problem better than anyone else does.
Next comes a trickier bit: what if you yourself get involved, even while "wearing a different hat", in one of these live controversies?
Your first line of defense is your own ethical conscience.
Another, as I suggested earlier, is to solicit one or more volunteers to serve as "deputy maintainers". Prepare a list of man pages or sections thereof upon which you are "conflicted out", and ask the deputies to field all Linux man-pages business regarding those pages/sections while you have business regarding those interfaces before a vendor libc and/or the WG14 committee. It will likely be obvious to you what vehicle can communicate these areas of deputy maintenance--a man page!
Quoted 7 lines
I intuit that Michael had a hard time finding anyone to take the mantle of Linux man-pages maintainership. It's a huge job and demanded someone of your unusual resources and energy. By opening deputy positions that are limited both in scope and in time, nobody need worry that they'll be expected to eat the whole elephant. If you find such volunteers, then you'll also be spreading expertise and socializing personal investment in the success of this project. That's good management!
I have a mental list of people to whom I consult when I don't think I should make the decision alone. The list isn't fixed, and varies wildly depending on the topics, but you can get an idea when I CC people in discussions. You've been yourself quite some times. :)
Quoted 3 lines
Finally, to return to the question of consensus: a potential point of development in Linux man-pages project governance is to
_documenthow you measureconsensus_.
Nope. I'll quote <https://isocpp.org/files/papers/P4238R0.pdf>:
2. How Consensus Is Supposed to Work
WG21 decides by consensus, not by vote. The chair, a subject-matter expert, weighs the arguments of every side. Where they can be reconciled, the chair reconciles them. Where they cannot be reconciled, the chair decides, and may decide against the numerical majority. This is deliberate: WG21's own guidance states that "the chair's determination of consensus is authoritative, not the straw poll" and that "we make decisions by consensus, not majority" (P2195R2), and ISO defines consensus as a process that takes all views into account and reconciles conflicting arguments, not a count of hands (ISO/IEC Directives Part 1, clause 2.5.6). The chair's authority is broad by design, and rightly so; a committee that decided technical questions by votes rather than expert judgment would be worse.
That is, I use my judgement as an expert. That's all we can document.
Quoted 7 lines
We'd be unwise to determine consensus by measuring who writes the most words (hi, folks), or with the angriest tone, or who has the most impressive job title at the biggest company, or who can shut down a discussion most coldly or derail it most effectively.
So tell the members of this community how _you_ measure it. Put the burden on the critical and the concerned to find flaws in your method.
At least, I've documented how and why I've valued the feedback from each one this (so-contentious) time.
If anyone wants to appeal, I'll be open to changing my mind based on new technical reasons.
Cheers,
Alex
Quoted 7 lines
Regards,
Branden[1] I'm not sure WG14 uses the term "motions", and I haven't seen much evidence that they use Robert's Rules of Order, with which Commonwealth people are likely not familiar, let alone non-Anglophones.
Signature · 1 line
<https://www.alejandro-colomar.es>
Re: [PATCH v2] man/man3/mem*(): SYNOPSIS: Document non-standard mem*() functions as provided by <memory.h>
In reply to Alejandro ColomarHi Alejandro,
All proposed ISO C changes need to be evaluated according to (at least) these three dimensions:
* Benefit (for the community of C programmers),
* Cost of adoption (for the community of C programmers),
* Consistency.
Your previous proposal "alx-0097r1 - <memory.h>, the legitimate header for memcpy(3) et al." evaluates like this, IMO:
* Benefit: Small.
* Cost of adoption: Huge
(there are more than 700000 references to memcpy() alone in Debian sources [1]).
* Consistency: Reasonable (you have explained why strncpy is actually a "mem" function).
This proposal [v2] is no longer for ISO C, but — if you want to teach the community something by modifying the man pages — needs to be evaluated according to the same criteria.
* Benefit: None.
* Cost of adoption: Moderate
(because these 5 functions are not frequently used).
* Consistency: Totally negative.
- memmem() is a generalization of memchr(), therefore it belongs in the same header file, namely <string.h>.
- memrchr() is an analogue to memchr(), therefore likewise it belongs in <string.h>.
- mempcpy() is a variant of memcpy(), therefore likewise it belongs in <string.h>.
- strndupa() is a variant of strndup() which is declared in <string.h>, therefore it belongs in <string.h> as well.
Please do us the favour to evaluate your proposals according to these dimensions by yourself, before spreading them.
And, of course, for man page changes, consider the authoritative source. For example, memfrob() exists only in glibc [2], therefore its authoritative documentation is in the glibc manual [3], and it says "It is declared in string.h." The man pages MUST say the same thing.
Thanks.
Bruno
[1] https://codesearch.debian.net/search?q=%5Cbmemcpy%5Cb&literal=0
[2] https://gitweb.git.savannah.gnu.org/gitweb/?p=gnulib/maint-tools.git;a=tree;f=platforms/various-symlists
[3] https://sourceware.org/glibc/manual/2.44/html_node/Obfuscating-Data.html
Alejandro Colomar
maintainerRe: on the irresponsibility of pursuing C language reform
In reply to Alejandro ColomarQuoted 81 lines
Date: 2026-08-02 00:22:37+0200
From: Alejandro Colomar <[email protected]>Hi Branden,
Quoted 11 lines
Date: 2026-08-01 16:34:21-0500
From: "G. Branden Robinson" <[email protected]>Hi Alex,
Quoted 3 lines · Alejandro Colomar
Well, Keith Bostic wouldn't have suggested that I do this change, and Branden wouldn't be defending that it might make sense to make this change.
I'm flattered to be mentioned in the same breath as Keith Bostic!
:)
Quoted 9 lines
Quoted 4 lines
A vocal majority is not consensus. Consensus would be if there were no significantly different or strongly opposed opinions to those of the majority. Even my strong and sustained opposition against your opinion already means there's no consensus against.
"Consensus" is a word that gets abused a lot, because it has multiple definitions. To some people it means "unanimity". To others, it means a majority vote with potentially many abstentions but no (or proportionally very few) negative votes.
Indeed.
Quoted 4 lines
From reading WG14 minutes, I'm
vaguely aware that it has a rubric for reading the straw polls they take when voting on N-papers and related motions.[1] I invite a member to cite a resource laying out their actual procedures.WG14, like WG21, has a problem. Consensus, these days, is taken as roughly a majority of votes.
With very few exceptions, here's the rule that guides consensus in straw polls during committee meetings:
// Consensus requires both // y/(y+n) >= 2/3 // n/(y+n+a) <= 1/4Strong opposition is dismissed as long as the numbers are okay. We even have a small program that performs that calculation and which we consult.
As a consequence, this is what happens (very interesting read):
<https://isocpp.org/files/papers/P4238R0.pdf>.A large number of NBs (national bodies), including mine, are going to vote against C++26, and as a consequence, it may be returned to WG21 for evaluation. This means we won't have C++26 if this happens.
Quoted 6 lines
I don't think I'm voicing a controversial view when I venture that Michael Kerrisk administered the Linux man-pages with a more settled view of the APIs it documents. By that, I mean that he tended to update its content with a retrospective view of matters that were no longer in contention. If some controversy brewed, he tended to omit it from "coverage" in the documentary corpus until the contention resolved.
Yup.
Quoted 3 lines
Your approach is a little different: you're more ready to give the reader a view of live controversies and unsettled matters troubling the C community where these intersect with the topics man-pages(7) covers.
Yup.
Quoted 1 line
Neither approach is better. They're just different.
Yup.
Quoted 4 lines
I think Sam is
right that people had many years to get used to Michael's approach. From there it's a short--but logically unsound--step to associate "familiar" with "better".
Quoted 8 lines
Yup.
Quoted 2 lines
But, if you're going to document unresolved controversies, how do you avoid putting a thumb on the scale?
Doing a lot of research. Whatever I don't research myself, I still act like Michael, and tend to not step into. But string and memory handling is something that has taken most of my time in the last 5 years or so.
In fact, I'd say I'm quite like Michael. It's just that Michael was an expert in other topics, more related to man2 and man7, and I'm more of an expert in libc (man3). Thus, Michael wrote quite a lot of somewhat- opinionated paragraphs in man2 and man7, which for some reason didn't trigger this amount of criticism (maybe because he added the text while the pages were added, and thus it didn't come as revisionism).
Cheers,
Alex
Quoted 151 lines
Quoted 3 lines
One way is to solicit review of that coverage for even-handedness--I do not say "neutrality". List pros and cons of competing interfaces or code idioms.
I do indeed get that. Mark gave me feedback about memccpy(3) recently, which I've incorporated to my research. That was the last issue I had with <
string.h>, because memccpy(3) is something I've never seen in real correct use. It seems Illumos is one of the places where they store that old knowledge. It's good that those projects still exist and can be used to learn about our history.Sam was concerned about not docuementing what standards say; and indeed, I'll make sure to document that (in STANDARDS, where it belongs; which I had already done, BTW). Other than that, he was worried that I might be encoding an opinion, but I believe this is a technical judgement based on research, and not an opinion. So, dismissed.
Joseph was concerned that this documentation would conflict with many documents saying that <
memory.h> is deprecated. Luckily, I've never seen such a document, so we can assume they don't exist (unless people show evidence). I'll dismiss his negative vote, since his technical reasons are incorrect. Also, <memory.h> is undoubtedly more portable than a new <stdmem.h>.It's also a bit Ironic that Joseph started with a strongly opinionated
proposal: deprecating <memory.h> in glibc (breaking 8.9k uses in Debian).Collin didn't comment, although by his support to Joseph's suggestion of deprecating <
memory.h>, I guess he's against. Since he didn't provide any new reasons, I guess it's more of Joseph's. Already dismissed, then.Nevin has an undeclared conflict of interest: He is the author of a proposal for WG14 to remove strncpy(3).
<https://www.open-std.org/jtc1/sc22/wg14/www/docs/n3935.htm>
Also, he didn't really give any technical reasons; he just voted no. A vote without reasons is still heard, but easily dismissed.Keith suggested doing this, by which I assume he's in favour. He's certainly an expert in the topic, and I'd value his support.
I value Doug's opinion too, although he didn't show much technical reasons this time. He was mostly concerned about changing string functions, but didn't clarify whether he was concerned about restoring <
memory.h>. Thus, I'd say I won't count that.You seem to support the fact that something should be done, except that you may not entirely agree with the approach. You've been a bit misguided by Joseph's concerns about <
memory.h>, so I'll dismiss that part of your feedback as being just Joseph's --which I've already dismissed on technical grounds--.Chris is concerned about my arbitrary separation, but I think his separation is also somewhat arbitrary. I'll trust my instinct here. We're always in time to revise this. In any case, this arbitrary distinction is better than the status quo.
Thus, with support from Keith, and no sustained opposition based on technical ground (Joseph didn't contest my response that absolutely no mainstream documents talk about <
memory.h> being deprecated, and himself said that it's only *implicitly* deprecated), I should commit.Quoted 22 lines
If you do that job correctly, _reasonable_ partisans of
the various contesting positions will find no cause to criticize. (There will sometimes be fanboys who object to the "opposition" getting any coverage at all.)Further, with such lists you do a service to the engineer who must select a means of solving the problem confronting them. The engineer often knows that problem better than anyone else does.
Next comes a trickier bit: what if you yourself get involved, even while "wearing a different hat", in one of these live controversies?
Your first line of defense is your own ethical conscience.
Another, as I suggested earlier, is to solicit one or more volunteers to serve as "deputy maintainers". Prepare a list of man pages or sections thereof upon which you are "conflicted out", and ask the deputies to field all Linux man-pages business regarding those pages/sections while you have business regarding those interfaces before a vendor libc and/or the WG14 committee. It will likely be obvious to you what vehicle can communicate these areas of deputy maintenance--a man page!
Quoted 7 lines
I intuit that Michael had a hard time finding anyone to take the mantle of Linux man-pages maintainership. It's a huge job and demanded someone of your unusual resources and energy. By opening deputy positions that are limited both in scope and in time, nobody need worry that they'll be expected to eat the whole elephant. If you find such volunteers, then you'll also be spreading expertise and socializing personal investment in the success of this project. That's good management!
I have a mental list of people to whom I consult when I don't think I should make the decision alone. The list isn't fixed, and varies wildly depending on the topics, but you can get an idea when I CC people in discussions. You've been yourself quite some times. :)
Quoted 3 lines
Finally, to return to the question of consensus: a potential point of development in Linux man-pages project governance is to
_documenthow you measureconsensus_.Nope. I'll quote <https://isocpp.org/files/papers/P4238R0.pdf>:
2. How Consensus Is Supposed to Work
WG21 decides by consensus, not by vote. The chair, a subject-matter expert, weighs the arguments of every side. Where they can be reconciled, the chair reconciles them. Where they cannot be reconciled, the chair decides, and may decide against the numerical majority. This is deliberate: WG21's own guidance states that "the chair's determination of consensus is authoritative, not the straw poll" and that "we make decisions by consensus, not majority" (P2195R2), and ISO defines consensus as a process that takes all views into account and reconciles conflicting arguments, not a count of hands (ISO/IEC Directives Part 1, clause 2.5.6). The chair's authority is broad by design, and rightly so; a committee that decided technical questions by votes rather than expert judgment would be worse.That is, I use my judgement as an expert. That's all we can document.
Quoted 7 lines
We'd be unwise to determine consensus by measuring who writes the most words (hi, folks), or with the angriest tone, or who has the most impressive job title at the biggest company, or who can shut down a discussion most coldly or derail it most effectively.
So tell the members of this community how _you_ measure it. Put the burden on the critical and the concerned to find flaws in your method.
At least, I've documented how and why I've valued the feedback from each one this (so-contentious) time.
If anyone wants to appeal, I'll be open to changing my mind based on new technical reasons.
Cheers,
AlexQuoted 7 lines
Regards,
Branden[1] I'm not sure WG14 uses the term "motions", and I haven't seen much evidence that they use Robert's Rules of Order, with which Commonwealth people are likely not familiar, let alone non-Anglophones.
Signature · 1 line
<https://www.alejandro-colomar.es>
Signature · 1 line
<https://www.alejandro-colomar.es>
Alejandro Colomar
maintainerRe: [PATCH v2] man/man3/mem*(): SYNOPSIS: Document non-standard mem*() functions as provided by <memory.h>
In reply to Bruno HaibleHi Bruno!
Quoted 12 lines
Date: 2026-08-02 00:22:34+0200
From: Bruno Haible <[email protected]>Hi Alejandro,
All proposed ISO C changes need to be evaluated according to (at least) these three dimensions:
* Benefit (for the community of C programmers),
* Cost of adoption (for the community of C programmers),
* Consistency.
Quoted 6 lines
Your previous proposal "alx-0097r1 - <
memory.h>, the legitimate header for memcpy(3) et al." evaluates like this, IMO:
* Benefit: Small.
* Cost of adoption: Huge
(there are more than 700000 references tomemcpy()alone in Debian sources [1]).
There's literally no change. The proposal includes this:
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>.
Which means that <string.h> is still a valid provider of memcpy(3), and thus absolutely no existing code breaks.
This is really a documentation change only. libc implementations that don't already have <memory.h> --i.e., Illumos gate, and gnulib, in the POSIX-ish world-- will have to do some work, but users won't.
Quoted 18 lines
* Consistency: Reasonable (you have explained why strncpy is actually a "mem" function).
This proposal [v2] is no longer for ISO C, but — if you want to teach the community something by modifying the man pages — needs to be evaluated according to the same criteria.
* Benefit: None.
* Cost of adoption: Moderate
(because these 5 functions are not frequently used).
* Consistency: Totally negative.
-memmem()is a generalization ofmemchr(), therefore it belongs in the same header file, namely <string.h>.
-memrchr()is an analogue tomemchr(), therefore likewise it belongs in <string.h>.
-mempcpy()is a variant ofmemcpy(), therefore likewise it belongs in <string.h>.
-strndupa()is a variant ofstrndup()which is declared in <string.h>, therefore it belongs in <string.h> as well.
Indeed, I've decided to do the entire set of v1, except I'll add some more text to NOTES documenting that <string.h> provides all of them too.
Quoted 2 lines
Please do us the favour to evaluate your proposals according to these dimensions by yourself, before spreading them.
Sure! Thanks!
Quoted 4 lines
And, of course, for man page changes, consider the authoritative source. For example,
memfrob()exists only in glibc [2], therefore its authoritative documentation is in the glibc manual [3], and it says "It is declared instring.h." The man pages MUST say the same thing.
Yes, in v3 (which I'll send soon), they'll say the same thing. That is, all the functions --standard or not-- will have text clarifying that the functions are also provided in <string.h>. This covers what glibc says. What goes in the SYNOPSIS is something I'll diverge from glibc, but that's fair game.
Thanks for the feedback!
Have a lovely night!
Alex
Quoted 10 lines
Thanks.
Bruno
[1] https://codesearch.debian.net/search?q=%5Cbmemcpy%5Cb&literal=0
[2] https://gitweb.git.savannah.gnu.org/gitweb/?p=gnulib/maint-tools.git;a=tree;f=platforms/various-symlists
[3] https://sourceware.org/glibc/manual/2.44/html_node/Obfuscating-Data.html
Signature · 1 line
<https://www.alejandro-colomar.es>
Alejandro Colomar
maintainerRe: on the irresponsibility of pursuing C language reform
In reply to a message not in the archiveHi Keith,
Quoted 6 lines
Date: 2026-08-01 15:22:49-0700
From: Keith Bostic <[email protected]>On Sat, Aug 1, 2026 at 10:09 AM Alejandro Colomar <[email protected]> wrote:
Quoted 7 lines
Well, Keith Bostic wouldn't have suggested that I do this change, and Branden wouldn't be defending that it might make sense to make this change.
Since my name came up: I did suggest man page changes, and I should have been clearer about what I meant.
Thanks!
Quoted 5 lines
I generally think innovation should happen in releases, in response to the user base. That’s the model with the better track record. Somebody ships something, users adopt it or they don’t, and the standards codify existing practice once it reaches consensus. When the standards bodies invent instead of codify, results have been uneven.
Fully agreed.
Quoted 8 lines
So if glibc added <
nonstring.h> tomorrow, that’s the system working. Ship it, let people vote with their code, and let the standard adopt if it wants.But as I understand it, the man-pages project doesn’t control the code it documents. It describes glibc and the kernel, it doesn’t ship them. A documentation project changing how coding should work in a release it doesn’t control feels different to me. So, my opinion is the man pages shouldn’t be changing the standard includes.
Actually, the documentation is for the system, not the standard. The system does provide <memory.h>, and thus it's fair game to document it, I believe.
Quoted 5 lines
Advocating for better usage in the documentation is a different thing, and a good thing. The man pages can even go pretty hard, that’s their job:
“Notice the include file isstring.h. That’s an historic accident maintained for compatibility reasons; don’t let that fool you, this function doesn’t operate on strings.”
Indeed. That's in essence what I'll do, with different wording.
The SYNOPSIS is the way of saying "don't let other sources fool you, this function doesn't work on strings, and you should include the system's <memory.h> to get it, which is compatible with all versions of libc".
The NOTES section is the way of documenting "but the standard says something different; let's ignore it".
--- HEAD^:man/man3/strdupa.3 +++ HEAD:man/man3/strdupa.3 @@ -11,6 +11,10 @@ SYNOPSIS #include <string.h> char *strdupa(const char *s); + + #define _GNU_SOURCE /* See feature_test_macros(7) */ + #include <memory.h> + char *strndupa(size_t n; const char s[n], size_t n); @@ -48,6 +52,9 @@ STANDARDS HISTORY GNU. +NOTES + The following header also provides strndupa(): <string.h>. + SEE ALSO alloca(3), strdup(3), strndup(3)
Quoted 4 lines
That teaches the reader what the function actually does without relabeling where it lives. I think it’s roughly what Joseph is suggesting as well, aiming the clarification at the reader’s understanding rather than at the SYNOPSIS line.
I should probably expand the NOTES a little bit, to be more clear about why we ignore the standard in the SYNOPSIS.
Have a lovely night!
Alex
Quoted 3 lines
—keith
[email protected]
Signature · 1 line
<https://www.alejandro-colomar.es>
Alejandro Colomar
maintainerRe: [PATCH v2] man/man3/mem*(): SYNOPSIS: Document non-standard mem*() functions as provided by <memory.h>
In reply to Bruno HaibleHi Bruno,
Quoted 3 lines
Date: 2026-08-02 00:55:46+0200
From: Bruno Haible <[email protected]>
[...]
Quoted 8 lines
Quoted 2 lines
Which means that <
string.h> is still a valid provider of memcpy(3), and thus absolutely no existing code breaks.Still, for the next 10 years, C programmers would debate whether they should #include <
string.h> or #include <memory.h>. Different C programmers in the same team will have different personal opinions. Thus, programmer team leads will have to establish coding styles/guidelines which say which header to include in this case.
I find that an acceptable result. #include's aren't that important. When reading code, the section of #include's is unimportant as long as it works.
I don't expect existing code to change, so this is a matter of what will happen in new files, or when a file is changed to newly use such a function.
Among the stylistic discussions that can happen, this is the least of our concerns. Also, if this triggers a discussion of _why_ this changed, we might have achieved something.
Quoted 5 lines
This is one of the challenges of language design: Each time the language offers several nearly equivalent ways of doing the same thing, different coding styles and the need for team guidelines are the consequence. C++ is particularly affected by this; Go hardly. Pushing C to become like C++, in this respect, would not be a good move.
We have precedent in <stdint.h> and <inttypes.h>. The world hasn't fallen over our heads so far. :)
Actually, <stdint.h> is just the tip of the ideberg. size_t is provided by 27 headers, if I counted well. And there's plenty of such examples. Another curious one is that there's something that's specified by ISO C to be defined in <time.h>, and by POSIX to be defined by <sys/time.h>. I don't remember what it was, but it was funny when I found out.
I've been involved for a few years in iwyu(1), contributing code for dealing with the standard includes from libc, and while we had our share of discussion of which headers are preferred for each symbol (we're some pedants, of course), I've never heard that such discussions reached the general public. The general public just wants a tool that says which are the right headers, and go with it.
Quoted 13 lines
The cost of adoption for this proposal is thus still big.
Quoted 10 lines
Quoted 4 lines
And, of course, for man page changes, consider the authoritative source. For example,
memfrob()exists only in glibc [2], therefore its authoritative documentation is in the glibc manual [3], and it says "It is declared instring.h." The man pages MUST say the same thing.Yes, in v3 (which I'll send soon), they'll say the same thing. That is, all the functions --standard or not-- will have text clarifying that the functions are also provided in <
string.h>. This covers what glibc says. What goes in the SYNOPSIS is something I'll diverge from glibc, but that's fair game.
Quoted 4 lines
I don't agree with you that it's "fair game". The SYNOPSIS is the first eye-catcher, often the only part that a programmer reads. It would be a disgrace if the man page, in the SYNOPSIS, mentions a different header than the authoritative source.
Some would question the fact that the glibc manual is the authoritative source for glibc documentation. :)
Quoted 1 line
Bruno
Cheers,
Alex
Signature · 1 line
<https://www.alejandro-colomar.es>
Re: [PATCH v2] man/man3/mem*(): SYNOPSIS: Document non-standard mem*() functions as provided by <memory.h>
In reply to Alejandro ColomarHi Alejandro,
Quoted 16 lines
Quoted 6 lines
Your previous proposal "alx-0097r1 - <
memory.h>, the legitimate header for memcpy(3) et al." evaluates like this, IMO:
* Benefit: Small.
* Cost of adoption: Huge
(there are more than 700000 references tomemcpy()alone in Debian sources [1]).There's literally no change. The proposal includes this:
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>.
Quoted 2 lines
Which means that <
string.h> is still a valid provider of memcpy(3), and thus absolutely no existing code breaks.
Still, for the next 10 years, C programmers would debate whether they should #include <string.h> or #include <memory.h>. Different C programmers in the same team will have different personal opinions. Thus, programmer team leads will have to establish coding styles/guidelines which say which header to include in this case.
This is one of the challenges of language design: Each time the language offers several nearly equivalent ways of doing the same thing, different coding styles and the need for team guidelines are the consequence. C++ is particularly affected by this; Go hardly. Pushing C to become like C++, in this respect, would not be a good move.
The cost of adoption for this proposal is thus still big.
Quoted 10 lines
Quoted 4 lines
And, of course, for man page changes, consider the authoritative source. For example,
memfrob()exists only in glibc [2], therefore its authoritative documentation is in the glibc manual [3], and it says "It is declared instring.h." The man pages MUST say the same thing.Yes, in v3 (which I'll send soon), they'll say the same thing. That is, all the functions --standard or not-- will have text clarifying that the functions are also provided in <
string.h>. This covers what glibc says. What goes in the SYNOPSIS is something I'll diverge from glibc, but that's fair game.
I don't agree with you that it's "fair game". The SYNOPSIS is the first eye-catcher, often the only part that a programmer reads. It would be a disgrace if the man page, in the SYNOPSIS, mentions a different header than the authoritative source.
Bruno
Alejandro Colomar
maintainerRe: on the irresponsibility of pursuing C language reform
In reply to Alejandro ColomarHi Keith,
Quoted 3 lines
Date: 2026-08-02 00:44:46+0200
From: Alejandro Colomar <[email protected]>
[...]
Quoted 6 lines
Quoted 5 lines
Advocating for better usage in the documentation is a different thing, and a good thing. The man pages can even go pretty hard, that’s their job:
“Notice the include file isstring.h. That’s an historic accident maintained for compatibility reasons; don’t let that fool you, this function doesn’t operate on strings.”
[...]
Quoted 2 lines
I should probably expand the NOTES a little bit, to be more clear about why we ignore the standard in the SYNOPSIS.
I've put that text in a centralized place, in the memory.h(3head) manual page:
$ MANWIDTH=64 diffman-git HEAD --- HEAD^:man/man3head/memory.h.3 +++ HEAD:man/man3head/memory.h.3 @@ -10,6 +10,11 @@ SYNOPSIS #include <memory.h>
DESCRIPTION
+ These functions are also provided in <string.h>, as speci‐
+ fied by ISO C. This is a historic accident maintained for
+ compatibility reasons. Don’t let that fool you; these
+ functions don’t necessarily operate on strings.
+
Write
bzero(3)
memset(3)
@@ -38,6 +43,19 @@ DESCRIPTION
memrchr(3)
memmem(3)
+STANDARDS
+ BSD.
+
+HISTORY
+ The <memory.h> header file is the original one which was
+ added in System V (1983), and was later adopted by 4.3BSD
+ (1986). It contained the original mem* functions.
+
+ C89 didn’t standardize this header file, and instead
+ crammed all these functions in <string.h>, resulting in
+ confusing programmers about the real purpose of these
+ functions.
+
SEE ALSO
string(3), string_copying(7)
Cheers,
Alex
Signature · 1 line
<https://www.alejandro-colomar.es>
Re: [PATCH v2] man/man3/mem*(): SYNOPSIS: Document non-standard mem*() functions as provided by <memory.h>
In reply to Alejandro ColomarQuoted 7 lines · Alejandro Colomar
Quoted 5 lines
Still, for the next 10 years, C programmers would debate whether they should #include <
string.h> or #include <memory.h>. Different C programmers in the same team will have different personal opinions. Thus, programmer team leads will have to establish coding styles/guidelines which say which header to include in this case.I find that an acceptable result.
But you aren't the only one who uses or references the man pages. From this thread, many people are not happy with the change.
Quoted 2 lines
#include's aren't that important. When reading code, the section of #include's is unimportant as long as it works.
In this case they won't "always work", hence your request that gnulib and illumos make changes to accommodate your preferences.
Quoted 7 lines
Quoted 4 lines
I don't agree with you that it's "fair game". The SYNOPSIS is the first eye-catcher, often the only part that a programmer reads. It would be a disgrace if the man page, in the SYNOPSIS, mentions a different header than the authoritative source.
Some would question the fact that the glibc manual is the authoritative source for glibc documentation. :)
I am not sure why it wouldn't be? It is what the glibc maintainers most actively update. It isn't perfect of course, but it does contain quite a lot of information:
$ pdfinfo manual/libc.pdf | grep '^Pages:'
Pages: 1284Collin
Alejandro Colomar
maintainerRe: [PATCH v2] man/man3/mem*(): SYNOPSIS: Document non-standard mem*() functions as provided by <memory.h>
Hi Collin,
Quoted 13 lines
Date: 2026-08-01 16:26:18-0700
From: Collin Funk <[email protected]>Quoted 7 lines · Alejandro Colomar
Quoted 5 lines
Still, for the next 10 years, C programmers would debate whether they should #include <
string.h> or #include <memory.h>. Different C programmers in the same team will have different personal opinions. Thus, programmer team leads will have to establish coding styles/guidelines which say which header to include in this case.I find that an acceptable result.
Quoted 8 lines
But you aren't the only one who uses or references the man pages. From this thread, many people are not happy with the change.
Quoted 2 lines
#include's aren't that important. When reading code, the section of #include's is unimportant as long as it works.
In this case they won't "always work", hence your request that gnulib and illumos make changes to accommodate your preferences.
I've now carefully documented that gnulib and Illumos don't provide this header. Thanks!
Have a lovely night!
Alex
Signature · 1 line
<https://www.alejandro-colomar.es>
Alejandro Colomar
maintainerRe: [PATCH v2] man/man3/mem*(): SYNOPSIS: Document non-standard mem*() functions as provided by <memory.h>
In reply to Paul EggertHi Paul,
Quoted 11 lines
Date: 2026-08-01 18:29:13-0500
From: Paul Eggert <[email protected]>Quoted 1 line · Alejandro Colomar
#include's aren't that important.
But this whole thread is about #includes, no?
I would focus energy on areas of the manual where effort provides the most bang for the buck. As your remark suggests, this particular area is low priority.
I wouldn't call it low priority or low bang for the buck. What I mean is that it's not a breaking change.
I believe education is important, and provides bang for the buck. It's not all about features. The features are already there, but misused.
Have a lovely night!
Alex
Quoted 2 lines
Also, given what I've seen in the thread so far, the proposed change could even yield a negative return overall.
Signature · 1 line
<https://www.alejandro-colomar.es>
Re: [PATCH v2] man/man3/mem*(): SYNOPSIS: Document non-standard mem*() functions as provided by <memory.h>
In reply to Alejandro ColomarQuoted 1 line · Alejandro Colomar
#include's aren't that important.
But this whole thread is about #includes, no?
I would focus energy on areas of the manual where effort provides the most bang for the buck. As your remark suggests, this particular area is low priority. Also, given what I've seen in the thread so far, the proposed change could even yield a negative return overall.
proposed revision to memory.h(3head) (was: on the irresponsibility of pursuing C language reform)
In reply to Alejandro ColomarHi Alex,
Quoted 23 lines · Alejandro Colomar
Quoted 3 lines
Date: 2026-08-02 00:44:46+0200
From: Alejandro Colomar <[email protected]>[...]
Quoted 6 lines
Quoted 5 lines
Advocating for better usage in the documentation is a different thing, and a good thing. The man pages can even go pretty hard, that’s their job: “Notice the include file is
string.h. That’s an historic accident maintained for compatibility reasons; don’t let that fool you, this function doesn’t operate on strings.”[...]
Quoted 2 lines
I should probably expand the NOTES a little bit, to be more clear about why we ignore the standard in the SYNOPSIS.
I've put that text in a centralized place, in the
memory.h(3head)manual page:$ MANWIDTH=64 diffman-git HEAD --- HEAD^:man/man3head/memory.h.3 +++ HEAD:man/man3head/memory.h.3 @@ -10,6 +10,11 @@ SYNOPSIS #include <memory.h>
Quoted 6 lines
DESCRIPTION
+ These functions are also provided in <string.h>, as speci‐
+ fied by ISO C. This is a historic accident maintained for
+ compatibility reasons. Don’t let that fool you; these
+ functions don’t necessarily operate on strings.
+
That's a heavy editorial slant. I don't think it was a historical accident; it was a historical "on purpose"[1], with which you disagree. Here's a revision that goes a little less hard, favors active voice over passive, and is shorter.
+ ISO C mandates that <string.h> declare these functions.
+ Be aware that they do not necessarily operate on strings.
Quoted 2 lines
+STANDARDS
+ BSD.
If you're tracking SVID in the Linux man-pages project, I would guess that it was in the original SVID, which formalized/specified SVr2--but I can't find online any version of SVID older than its Fourth Edition.
If you care about SVID, this point may bear further research. Matt G. of TUHS might have a line on older editions of SVID.
Quoted 9 lines
+HISTORY
+ The <memory.h> header file is the original one which was
+ added in System V (1983), and was later adopted by 4.3BSD
+ (1986). It contained the original mem* functions.
+
+ C89 didn’t standardize this header file, and instead
+ crammed all these functions in <string.h>, resulting in
+ confusing programmers about the real purpose of these
+ functions.
Again, you're going harder than you need to here.
I propose:
+HISTORY
+ System V (1983) introduced an initial set of mem*
+ functions in a <memory.h> file. 4.3BSD (1986) adopted
+ them. C89 specified them in <string.h>.
+
+ The programmer bears the burden of selecting appropriate
+ functions for operations on memory buffers (which may
+ contain any bytes, including nulls) versus strings (which
+ null bytes terminate).
If you like the foregoing, consider it:
Regards,
Branden
[1] As one does with "all the glue", when one doesn't want a "major award" to be readily repaired...
the Linux man-pages as an educational tool (was: [PATCH v2] man/man3/mem*(): SYNOPSIS: Document non-standard mem*() functions as provided by <memory.h>)
In reply to Alejandro ColomarQuoted 12 lines · Alejandro Colomar
Quoted 11 lines
Date: 2026-08-01 18:29:13-0500
From: Paul Eggert <[email protected]>Quoted 1 line · Alejandro Colomar
#include's aren't that important.
But this whole thread is about #includes, no?
I would focus energy on areas of the manual where effort provides the most bang for the buck. As your remark suggests, this particular area is low priority.
Quoted 6 lines
I wouldn't call it low priority or low bang for the buck. What I mean is that it's not a breaking change.
I believe education is important, and provides bang for the buck. It's not all about features. The features are already there, but misused.
I'd like to underscore this point. As I noted in my response to Doug, the flagship book on C, as we all know, is stuck in 1988. The throne is vacant, with many pretenders, some with excellent cases for service as regent.
But no head wears the crown.
And at the same time many C programmers are shy of consulting the formal standard. We can lament their lack of wisdom in doing so and in failing to spin themselves up in standardese sufficiently to grapple with it.
But we can also throw 'em a bone. To where shall they turn?
Sure, if they're in Emacs, they might go to glibc's Info manual.
But some people dislike Info, and some people use a different libc.
So what remains for the motley crew left behind?
The man pages.
I think people come to the Linux man-pages in part to learn C. When I was starting out, long ago, I wondered why there wasn't a man page for the language itself. Years later, I learned that there once sort of had been, in the 1970s. It was Ritchie's "C Reference Manual".[1]
But it wasn't on any Unix machine I had access to.
Why not?
Because Prentice-Hall didn't want it there. And still don't, I guess.
https://www.tuhs.org/cgi-bin/utree.pl?file=V7/usr/doc/cman
Maybe education is not a job the Linux man-pages project _should_ have, but it is one that has been thrust upon it.
Regards,
Branden
[1] Not a man page, but you could render it intelligibly with nroff.
Alejandro Colomar
maintainerRe: proposed revision to memory.h(3head) (was: on the irresponsibility of pursuing C language reform)
In reply to G. Branden RobinsonHi Branden,
Quoted 34 lines
Date: 2026-08-01 18:53:32-0500
From: "G. Branden Robinson" <[email protected]>Quoted 23 lines · Alejandro Colomar
Quoted 3 lines
Date: 2026-08-02 00:44:46+0200
From: Alejandro Colomar <[email protected]>[...]
Quoted 6 lines
Quoted 5 lines
Advocating for better usage in the documentation is a different thing, and a good thing. The man pages can even go pretty hard, that’s their job: “Notice the include file is
string.h. That’s an historic accident maintained for compatibility reasons; don’t let that fool you, this function doesn’t operate on strings.”[...]
Quoted 2 lines
I should probably expand the NOTES a little bit, to be more clear about why we ignore the standard in the SYNOPSIS.
I've put that text in a centralized place, in the
memory.h(3head)manual page:$ MANWIDTH=64 diffman-git HEAD --- HEAD^:man/man3head/memory.h.3 +++ HEAD:man/man3head/memory.h.3 @@ -10,6 +10,11 @@ SYNOPSIS #include <memory.h>Quoted 6 lines
DESCRIPTION
+ These functions are also provided in <string.h>, as speci‐
+ fied by ISO C. This is a historic accident maintained for
+ compatibility reasons. Don’t let that fool you; these
+ functions don’t necessarily operate on strings.
+
Quoted 2 lines
That's a heavy editorial slant. I don't think it was a historical accident; it was a historical "on purpose"[1], with which you disagree.
[pasted [1] here]
Quoted 2 lines
[1] As one does with "all the glue", when one doesn't want a "major award" to be readily repaired...
The C89 Rationale document doesn't document this as an intentional change (or even as a change at all).
<https://www.open-std.org/jtc1/sc22/wg14/www/C89Rationale.pdf>
I'd certainly be interested in hearing first-hand information, if anyone has it. Maybe Keith would be the best candidate for that.
Quoted 5 lines
Here's a revision that goes a little less hard, favors active voice over passive, and is shorter.
+ ISO C mandates that <
string.h> declare these functions.
+ Be aware that they do not necessarily operate on strings.
I'll think about it.
Quoted 7 lines
Quoted 3 lines
+STANDARDS
+ BSD.If you're tracking SVID in the Linux man-pages project, I would guess that it was in the original SVID, which formalized/specified SVr2--but I can't find online any version of SVID older than its Fourth Edition.
Here's an online copy of SVID Issue 2:
<https://bitsavers.org/pdf/att/unix/SVID/System_V_Interface_Definition_Issue_2_Volume_1_1986.pdf>
It does indeed standardize <memory.h>.
I don't know of any copy of SVID Issue 1.
SVID is a withdrawn standard (having been superseded by the SUS/POSIX standards, Issue 8 in the most recent revision), and thus not appropriate for STANDARDS. It'd be however appropriate for HISTORY. However, the SVID 1 corresponds to SVr2 (1985), so that's actually too late for this. In HISTORY, I've documented this as SysV (maybe we should coin SVr1? It doesn't exist in standards(7), but it'd be reasonable).
At the moment, I have it as:
STANDARDS BSD. HISTORY SysV, 4.3BSD. ...
Also, we don't document the SVID documents in HISTORY, because we document the corresponding revision of SysV.
Interestingly, POSIX.1-1988 already moved everything to <string.h> (C89 was almost finalized by then) and doesn't contain any references to <memory.h>, as if it had never existed.
<https://nvlpubs.nist.gov/nistpubs/Legacy/FIPS/fipspub151-1.pdf>
I'd be curious to see whether XPG Issue 3 still kept <memory.h> (but I suspect it won't, since it derives from POSIX.1-1988). SVID Third Edition curiously removed any mentions of <memory.h>, as if it had never existed (just like POSIx.1-1988).
<https://archive.org/details/systemvinterface0001unse/page/n149/mode/1up?q=memory.h>
(For anyone reading and wondering about the incestuous relationship of
these old standards, here's a useful rough sketch I did some time ago):
<https://lore.kernel.org/linux-man/aWwzhLaG_aehhWOG@devuan/>
Quoted 2 lines
If you care about SVID, this point may bear further research. Matt G. of TUHS might have a line on older editions of SVID.
I'd be interesting to have a copy of those, for sure. I am aware of the copies of Issue 2 and Third Edition I linked above, but I'd certainly be interested in a copy of Issue 1. XPG 3 would also be nice.
Quoted 10 lines
Quoted 9 lines
+HISTORY
+ The <memory.h> header file is the original one which was
+ added in System V (1983), and was later adopted by 4.3BSD
+ (1986). It contained the original mem* functions.
+
+ C89 didn’t standardize this header file, and instead
+ crammed all these functions in <string.h>, resulting in
+ confusing programmers about the real purpose of these
+ functions.
Quoted 8 lines
Again, you're going harder than you need to here.
I propose:
+HISTORY
+ System V (1983) introduced an initial set of mem*
+ functions in a <memory.h> file. 4.3BSD (1986) adopted
+ them. C89 specified them in <string.h>.
I like part of this paragraph.
Quoted 4 lines
+ The programmer bears the burden of selecting appropriate + functions for operations on memory buffers (which may + contain any bytes, including nulls) versus strings (which + null bytes terminate).
I'm not convinced.
Quoted 4 lines
If you like the foregoing, consider it:
Signed-off-by G. Branden Robinson <[email protected]>
I'll probably modify it and note it as
Suggested-by: ...
Cheers,
Alex
Signature · 1 line
<https://www.alejandro-colomar.es>
Alejandro Colomar
maintainerRe: the Linux man-pages as an educational tool (was: [PATCH v2] man/man3/mem*(): SYNOPSIS: Document non-standard mem*() functions as provided by <memory.h>)
In reply to G. Branden RobinsonHi Branden,
Quoted 19 lines
Date: 2026-08-01 19:08:33-0500
From: "G. Branden Robinson" <[email protected]>Quoted 15 lines · Alejandro Colomar
Quoted 11 lines
Date: 2026-08-01 18:29:13-0500
From: Paul Eggert <[email protected]>Quoted 1 line · Alejandro Colomar
#include's aren't that important.
But this whole thread is about #includes, no?
I would focus energy on areas of the manual where effort provides the most bang for the buck. As your remark suggests, this particular area is low priority.
I wouldn't call it low priority or low bang for the buck. What I mean is that it's not a breaking change.
Quoted 8 lines
Quoted 3 lines
I believe education is important, and provides bang for the buck. It's not all about features. The features are already there, but misused.
I'd like to underscore this point. As I noted in my response to Doug, the flagship book on C, as we all know, is stuck in 1988. The throne is vacant, with many pretenders, some with excellent cases for service as regent.
In fact, the throne might currently fall in the Linux man-pages project. While not being a blood heir of the Unix standards, it has become a de-facto standard.
After all, both POSIX and C89 in one way or the other derive from the Unix and System V manual pages (you can see it in their structure and formatting). Unix and System V were the largest systems of their age, and GNU+Linux is currently in that position. It's natural that its manual pages are the current de-facto standard (no, not the texinfo docs).
Quoted 11 lines
But no head wears the crown.
And at the same time many C programmers are shy of consulting the formal standard. We can lament their lack of wisdom in doing so and in failing to spin themselves up in standardese sufficiently to grapple with it.
But we can also throw 'em a bone. To where shall they turn?
Sure, if they're in Emacs, they might go to glibc's Info manual.
But some people dislike Info, and some people use a different libc.
Michael was wise to document different libc's, including the BSDs, in the manual pages, which is why they've become a standard. If he had limited to just glibc and Linux, it might not have been the case.
Quoted 3 lines
So what remains for the motley crew left behind?
The man pages.
Indeed.
Quoted 4 lines
I think people come to the Linux man-pages in part to learn C. When I was starting out, long ago, I wondered why there wasn't a man page for the language itself. Years later, I learned that there once sort of had been, in the 1970s. It was Ritchie's "C Reference Manual".[1]
Hmmm, indeed, I believe that is the place to have it. It doesn't make much sense to document only part of the language in the pages but not all of it. FWIW, I've been documenting attributes and operators in the manual pages recently. We're closing the gap.
Quoted 7 lines
But it wasn't on any Unix machine I had access to.
Why not?
Because Prentice-Hall didn't want it there. And still don't, I guess.
Hmmm. Is there any copy of that?
Quoted 1 line
Maybe education is not a job the Linux man-pages project _should_ have,
I don't see why. In fact, I believe it's its ultimate job.
If documentation for a car was an aseptic piece of text describing it mechanically but not saying how to use it, it wouldn't be much good. It doesn't need to teach you how to drive (that's for driving schools), but it certainly must educate the driver about the limitations of the car, such as "this vehicle can lift from the ground if you drive at 300 mph, don't reach this speed". Or "if you have a lateral hit, the airbag won't protect you".
Same happens here.
Cheers,
Alex
Quoted 6 lines
but it is one that has been thrust upon it.
Regards,
Branden[1] Not a man page, but you could render it intelligibly with nroff.
Signature · 1 line
<https://www.alejandro-colomar.es>
Alejandro Colomar
maintainerRe: proposed revision to memory.h(3head) (was: on the irresponsibility of pursuing C language reform)
In reply to Alejandro ColomarQuoted 7 lines
Date: 2026-08-02 02:27:44+0200
From: Alejandro Colomar <[email protected]>Quoted 4 lines
Date: 2026-08-01 18:53:32-0500
From: "G. Branden Robinson" <[email protected]>At 2026-08-02T01:24:28+0200, Alejandro Colomar wrote:
[...]
Quoted 14 lines
Quoted 9 lines
Quoted 6 lines
DESCRIPTION
+ These functions are also provided in <string.h>, as speci‐
+ fied by ISO C. This is a historic accident maintained for
+ compatibility reasons. Don’t let that fool you; these
+ functions don’t necessarily operate on strings.
+That's a heavy editorial slant. I don't think it was a historical accident; it was a historical "on purpose"[1], with which you disagree.
[pasted [1] here]
Quoted 2 lines
[1] As one does with "all the glue", when one doesn't want a "major award" to be readily repaired...
Quoted 6 lines
The C89 Rationale document doesn't document this as an intentional change (or even as a change at all).
<https://www.open-std.org/jtc1/sc22/wg14/www/C89Rationale.pdf>I'd certainly be interested in hearing first-hand information, if anyone has it. Maybe Keith would be the best candidate for that.
Actually, s/accident/mistake/ is more correct. It was most likely done on purpose, even if unaware of the consequences it would have. That's not an accident but a mistake.
Cheers,
Alex
Signature · 1 line
<https://www.alejandro-colomar.es>
Re: the Linux man-pages as an educational tool
In reply to Alejandro ColomarQuoted 8 lines · Alejandro Colomar
Quoted 4 lines
I'd like to underscore this point. As I noted in my response to Doug, the flagship book on C, as we all know, is stuck in 1988. The throne is vacant, with many pretenders, some with excellent cases for service as regent.
In fact, the throne might currently fall in the Linux man-pages project. While not being a blood heir of the Unix standards, it has become a de-facto standard.
I don't think anyone is arguing whether or not man-pages is an educational tool. The argument is whether it should educate based on current standards, or the maintainers preferences.
Collin
Re: the Linux man-pages as an educational tool
Hi Collin,
Quoted 6 lines · Collin Funk
Quoted 5 lines · Alejandro Colomar
Quoted 4 lines
I'd like to underscore this point. As I noted in my response to Doug, the flagship book on C, as we all know, is stuck in 1988. The throne is vacant, with many pretenders, some with excellent cases for service as regent.
Quoted 7 lines
Quoted 3 lines
In fact, the throne might currently fall in the Linux man-pages project. While not being a blood heir of the Unix standards, it has become a de-facto standard.
I don't think anyone is arguing whether or not man-pages is an educational tool. The argument is whether it should educate based on current standards, or the maintainers preferences.
There are always going to be matters that a relevant standards body hasn't resolved. Its work would be trivial if there weren't!
I think what the Linux man-pages community is negotiating here is a pair of related questions.
1. Should the Linux man-pages make _any_ representations that are not supported by a formal standard?
2. If so, what are the boundaries of its editorial authority?
3. If not, hard luck for the Linux kernel, eh?
It's easy to say, "I don't like what Alex is doing with xyz(3)." What's harder is to articulate a reasonable-sounding, defensible principle that should restrain him from doing so.
As Kant said:
"Act only according to that maxim whereby you can at the same time will that it should become a universal law."
https://existentialcomics.com/comic/293
Regards,
Branden
Alejandro Colomar
maintainerRe: the Linux man-pages as an educational tool
In reply to Collin FunkHi Collin,
Quoted 10 lines
Date: 2026-08-01 18:04:05-0700
From: Collin Funk <[email protected]>Quoted 5 lines · Alejandro Colomar
Quoted 4 lines
I'd like to underscore this point. As I noted in my response to Doug, the flagship book on C, as we all know, is stuck in 1988. The throne is vacant, with many pretenders, some with excellent cases for service as regent.
Quoted 7 lines
Quoted 3 lines
In fact, the throne might currently fall in the Linux man-pages project. While not being a blood heir of the Unix standards, it has become a de-facto standard.
I don't think anyone is arguing whether or not man-pages is an educational tool. The argument is whether it should educate based on current standards, or the maintainers preferences.
I'm not innovating if I say that the standards are mostly ignored. Actually, I am more in the side of following the standards as much as possible and appropriate (but not more) on average.
This is just a case where educating on the current standards is done by
1) documenting at the bottom of the manual what the standard says, and
2) recommending to ignore it because it's bad. When the standards are bad, this is appropriate course.
The manual pages should certainly educate about reality, and standards are only secondary to that.
This reminds me of realloc(3). That's a perfect example of educating based on current (and withdrawn) standards. And the education might very well consist of saying "don't listen to the standards in this case; they're bad for you".
I expect we'll be able to fix realloc(p,0) eventually, and Microsoft is working with me on that.
STANDARDS
...
realloc(p, 0)
The behavior of realloc(p, 0) in glibc doesn’t conform to any of C99, C11, POSIX.1‐2001, POSIX.1‐2004, POSIX.1‐2008,
POSIX.1‐2013, POSIX.1‐2017, or POSIX.1‐2024. The C17
specification was changed to make it conforming, but that specification made it impossible to write code that reli‐ ably determines if the input pointer is freed after real‐ loc(p, 0), and C23 changed it again to make this undefined behavior, acknowledging that the C17 specification was broad enough, so that undefined behavior wasn’t worse than that.
reallocarray() suffers the same issues in glibc.
musl libc and the BSDs conform to all versions of ISO C and POSIX.1.
gnulib provides the realloc‐posix module, which provides wrappers realloc() and reallocarray() that conform to all versions of ISO C and POSIX.1.
There’s a proposal to standardize the BSD behavior: https:
//www.open-std.org/jtc1/sc22/wg14/www/docs/n3621.txt.
HISTORY
...
realloc(p, 0)
C89 was ambiguous in its specification of realloc(p, 0). C99 partially fixed this.
The original implementation in glibc would have been con‐ forming to C99. However, and ironically, trying to comply with C99 before the standard was released, glibc changed its behavior in glibc 2.1.1 into something that ended up not conforming to the final C99 specification (but this is debated, as the wording of the standard seems self‐contra‐ dicting).
...
BUGS
Programmers would naturally expect by induction that realloc(p, size) is consistent with free(p) and mal‐ loc(size), as that is the behavior in the general case. This is not explicitly required by POSIX.1‐2024 or C11, but all conforming implementations are consistent with that.
The glibc implementation of realloc() is not consistent with that, and as a consequence, it is dangerous to call realloc(p, 0) in glibc.
A trivial workaround for glibc is calling it as
realloc(p, size?size:1).
The workaround for reallocarray() in glibc ——which shares
the same bug—— would be
reallocarray(p, n?n:1, size?size:1).
Have a lovely night!
Alex
Quoted 2 lines
Collin
Signature · 1 line
<https://www.alejandro-colomar.es>
Re: the Linux man-pages as an educational tool
Quoted 8 lines · Alejandro Colomar
I'm not innovating if I say that the standards are mostly ignored. Actually, I am more in the side of following the standards as much as possible and appropriate (but not more) on average.
This is just a case where educating on the current standards is done by
1) documenting at the bottom of the manual what the standard says, and
2) recommending to ignore it because it's bad. When the standards are bad, this is appropriate course.
But myself and likely many others who have commented on this thread do not agree that strings.h is a bad name. Or that general memory related functions, which are used on strings a large portion of the time, need a separate header.
In one of your original messages you mentioned the following:
Quoted 6 lines
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, for example leading to believe that strncpy(3) is appropriate to handle strings.
Quoted 3 lines · in another you
I find that an acceptable result. #include's aren't that important. When reading code, the section of #include's is unimportant as long as it works.
If I concede that "#include's aren't that important", then strncpy still exists and still looks like a function that should be used on strings. So, we have still have the same problem unaddressed, right? People will still use the function and write bugs.
Quoted 2 lines
The manual pages should certainly educate about reality, and standards are only secondary to that.
The current reality and standards are fully in alignment here. memcpy et al. have been defined in string.h since before I was born. Anyone who knows of memory.h knows that they can just do s/memory/string/ and make their code look more recent. Anyone who doesn't know about memory.h will be confused why the man-pages tell them to use a different header than they have used for decades. New programmers will follow those instructions and find their code breaks on illumos, when it really shouldn't.
Collin
Alejandro Colomar
maintainerRe: the Linux man-pages as an educational tool
Hi Collin,
Quoted 14 lines
Date: 2026-08-01 18:49:03-0700
From: Collin Funk <[email protected]>Quoted 8 lines · Alejandro Colomar
I'm not innovating if I say that the standards are mostly ignored. Actually, I am more in the side of following the standards as much as possible and appropriate (but not more) on average.
This is just a case where educating on the current standards is done by
1) documenting at the bottom of the manual what the standard says, and
2) recommending to ignore it because it's bad. When the standards are bad, this is appropriate course.
Quoted 4 lines
But myself and likely many others who have commented on this thread do not agree that
strings.his a bad name. Or that general memory related functions, which are used on strings a large portion of the time, need a separate header.
This is an opinion, which I respect, but don't agree with.
The vocal many people with that opinion have had 37 years to show how the solution to string handling bugs was a different one.
I've done my research, and am convinced that this is an unintrusive partial solution. As the ultimate responsible of this documentation project, I'll commit to this solution. Time will tell whether I am wrong. I think string handling is already so messed in people's heads, that at worst this solution won't do any noticeable good or bad, and at best it might put an end to the problem.
Quoted 9 lines
In one of your original messages you mentioned the following:
Quoted 6 lines
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, for example leading to believe that strncpy(3) is appropriate to handle strings.
Quoted 7 lines
Quoted 3 lines · in another you
I find that an acceptable result. #include's aren't that important. When reading code, the section of #include's is unimportant as long as it works.
If I concede that "#include's aren't that important",
That sentence was in context. #include's aren't that important in code. They are important in documentation and education (as I replied to Paul).
Quoted 3 lines
then strncpy still
exists and still looks like a function that should be used on strings.
The documentation part (including the global header classification, which appears in the SYNOPSIS) is what makes (or should make) it not look like a function that should be used on strings.
The name should also be part of that, but that ship sailed. We could actually also attempt at fixing the name, like the Linux kernel has done, but that's a different topic.
Quoted 8 lines
So, we have still have the same problem unaddressed, right? People will still use the function and write bugs.
Quoted 2 lines
The manual pages should certainly educate about reality, and standards are only secondary to that.
The current reality and standards are fully in alignment here. memcpy et al. have been defined in
string.hsince before I was born.
And they have also been defined in <memory.h> since before you and I were born.
Quoted 5 lines
Anyone who
knows ofmemory.hknows that they can just do s/memory/string/ and make their code look more recent. Anyone who doesn't know aboutmemory.hwill be confused why the man-pages tell them to use a different header than they have used for decades.
That's why I've documented the reason in memory.h(3head).
Quoted 3 lines
New programmers will follow those
instructions and find their code breaks on illumos, when it really shouldn't.
I hope Illumos adds <memory.h>. Also, I don't expect new programmers to be exactly the kind of programmers that use Illumos.
Quoted 1 line
Collin
Have a lovely day!
Alex
Signature · 1 line
<https://www.alejandro-colomar.es>
Alejandro Colomar
maintainerRe: the Linux man-pages as an educational tool
Hi Collin,
Quoted 7 lines
Quoted 7 lines
Date: 2026-08-01 18:49:03-0700
From: Collin Funk <[email protected]>But myself and likely many others who have commented on this thread do not agree that
strings.his a bad name. Or that general memory related functions, which are used on strings a large portion of the time, need a separate header.
BTW, this typo reminds me that we have some more evidence. <strings.h> has existed for a long time in parallel to <string.h>, and some functions are documented as being provided by it instead of by <string.h>. An example is strcasecmp(3).
In practice, both <string.h> and <strings.h> provide strcasecmp(3):
alx@devuan:~/tmp$ cat s.c #include <string.h>
int
main(void)
{
void *p = strcasecmp;
}
alx@devuan:~/tmp$ gcc -Wall -Wextra -Wno-unused s.c
alx@devuan:~/tmp$ Every now and then, people wonder about this non-standard header file, but no cats were harmed by that. Claiming that <memory.h> would be much different is unreasonable, IMO.
Cheers,
Alex
Signature · 1 line
<https://www.alejandro-colomar.es>
Alejandro Colomar
maintainerRe: the Linux man-pages as an educational tool
In reply to Alejandro ColomarQuoted 8 lines
Date: 2026-08-02 03:15:43+0200
From: Alejandro Colomar <[email protected]>Quoted 5 lines
Date: 2026-08-01 18:04:05-0700
From: Collin Funk <[email protected]>Alejandro Colomar <[email protected]> writes:
[...]
Quoted 14 lines
Quoted 4 lines
I don't think anyone is arguing whether or not man-pages is an educational tool. The argument is whether it should educate based on current standards, or the maintainers preferences.
I'm not innovating if I say that the standards are mostly ignored. Actually, I am more in the side of following the standards as much as possible and appropriate (but not more) on average.
This is just a case where educating on the current standards is done by
1) documenting at the bottom of the manual what the standard says, and
2) recommending to ignore it because it's bad. When the standards are bad, this is appropriate course.
Quoted 7 lines
The manual pages should certainly educate about reality, and standards are only secondary to that.
This reminds me of realloc(3). That's a perfect example of educating based on current (and withdrawn) standards. And the education might very well consist of saying "don't listen to the standards in this case; they're bad for you".
And let me expand on this. realloc(p,0) is not just example and precedent of how documentation *must* go against the standards when appropriate. It's also an example of how the manual pages must and will go against the partial specification of glibc's official manual.
We would do programmers a disservice if the manual pages limited to mirror what glibc's manual says.
Where the glibc documentation doesn't document its own perils, we must deviate from that, and document them clearly.
Cheers,
Alex
Signature · 1 line
<https://www.alejandro-colomar.es>
Re: on the irresponsibility of pursuing C language reform
In reply to Alejandro ColomarI'm just a lurker, but let me offer my perspective on this.
Header files in C and C++ are in large part a nuisance and a historical relic. If I call function x, I must include header <y.h>. The mapping between x and y is partly sensible, but partly arbitrary.
Since I program in C and/or C++ every day, I can usually remember that mapping, but when I can't, I immediately check the man page, and I'm glad that (unlike in the old days) the Synopsis section always reminds me which header to include.
Although I said header files are a nuisance, in one key respect they're less of a nuisance than they used to be, because *the C and C++ standards standardize them*. This is a huge, huge win. Back in the day you never knew if you could or should use reasonable-looking headers like <memory.h> or <malloc.h>. But today, it's a no-brainer. There's one right answer. If I use the Standard header in my code, and my code fails to compile under some brain-dead compiler tomorrow, it's that compiler's fault, not mine. I don't care a bit whether the Standard's mappings do or don't make sense; the fact that they're standard trumps anything else.
Now, this is one man's perspective, and I concede that I'm not an average C or C++ programmer, either. Me, I could check the Standard, because I have PDF copies of every version of the C Standard right here on my laptop, but for this sort of question I typically don't, because typing "man memset" is so much quicker. I don't know what the average programmer does, but I would heartily advocate for a high-quality man page to give the Right answer, where the Right answer for standard functions is precisely what the Standard says.
Now, there are always interesting arguments to be had about which of the library functions still hold their weight today, which of them might be deprecated or replaced with something newer, and how to educate users about evolving best practices. Certainly, today, strncpy and strncat are the new gets. (As it happens, I've been spending real time just in the past few weeks coping with the fact that not every Linux C compiler I use ships with a glibc that supports strlcpy and strlcat.)
But with that said, the place for those "interesting arguments" is not a man page! Man pages are supposed to be maximally pithy. Just the facts, ma'am.
Finally, I really don't think that the the mapping between function x and header <y.h>, a mapping which I characterized as somewhat arbitrary, is something that the average programmer pays that much attention to. If strncpy or memset is to be found in a header called <string.h>, that doesn't tell us that these functions operate on strings, any more than ssprintf appearing in <stdio.h> implies that ssprintf does I/O. So let's put the arguing, and the opinionating, and the educating, somewhere else, and have the man pages document (nay, recommend) precisely the headers that the Standard(s) say are standard.
Steve Summit
Alejandro Colomar
maintainerRe: on the irresponsibility of pursuing C language reform
Hi Steve,
Quoted 3 lines
Date: 2026-08-02 08:52:04-0400
From: Steve Summit <[email protected]>
[...]
Quoted 2 lines
Certainly,
today, strncpy and strncat are the new gets.
This is deeply incorrect.
gets(3) is a function that can't possibly be used safely.
strncpy(3) is a fine function for copying a string into a fixed-width buffer. strncat(3) is a fine function for appending a [[gnu::nonstring]] to a string. strncpy/cat(3) are bad when they are misused, just like a screwdriver is bad for hammering nails.
gets(3) is not that.
This is something that even most of the people disagreeing to this proposed change agree with.
Quoted 4 lines
(As it happens,
I've been spending real time just in the past few weeks coping with the fact that not every Linux C compiler I use ships with a glibc that supports strlcpy and strlcat.)
strlcpy/cat(3) have their own issues, although admittedly a DoS is better than a buffer overflow.
Ideally, you should be looking for strscpy(9); but you should write it yourself, because it's not provided by any libraries.
Quoted 3 lines
But with that said, the place for those "interesting arguments" is not a man page! Man pages are supposed to be maximally pithy. Just the facts, ma'am.
"The facts" is more subjective than it seems at first glance.
Just some examples of manual pages before I touched them, to show that I'm not even innovating. Maybe because I CC people I know disagree with me, I get more vocal opposition, I guess.
Here's part of str[n]cpy(3) well before I got involved in the project.
DESCRIPTION
The strcpy() function copies the string pointed to by src, including the terminating null byte ('\0'), to the buffer pointed to by dest. The strings may not overlap, and the destination string dest must be large enough to receive the copy. Beware of buffer overruns! (See BUGS.)
The strncpy() function is similar, except that at most n bytes of src are copied. Warning: If there is no null byte among the first n bytes of src, the string placed in dest will not be null‐terminated.
If the length of src is less than n, strncpy() writes ad‐ ditional null bytes to dest to ensure that a total of n bytes are written.
A simple implementation of strncpy() might be:
char *
strncpy(char *dest, const char *src, size_t n) {
size_t i;
for (i = 0; i < n && src[i] != '\0'; i++)
dest[i] = src[i];
for ( ; i < n; i++)
dest[i] = '\0';
return dest;
}
NOTES
Some programmers consider strncpy() to be inefficient and error prone. If the programmer knows (i.e., includes code to test!) that the size of dest is greater than the length of src, then strcpy() can be used.
One valid (and intended) use of strncpy() is to copy a C string to a fixed‐length buffer while ensuring both that the buffer is not overflowed and that unused bytes in the destination buffer are zeroed out (perhaps to prevent in‐ formation leaks if the buffer is to be written to media or transmitted to another process via an interprocess commu‐ nication technique).
If there is no terminating null byte in the first n bytes of src, strncpy() produces an unterminated string in dest. If buf has length buflen, you can force termination using something like the following:
if (buflen > 0) {
strncpy(buf, str, buflen - 1); buf[buflen - 1]= '\0';
}
(Of course, the above technique ignores the fact that, if src contains more than buflen - 1 bytes, information is lost in the copying to dest.)
strlcpy()
Some systems (the BSDs, Solaris, and others) provide the following function:
size_t strlcpy(char *dest, const char *src, size_t
size);
This function is similar to strncpy(), but it copies at most size-1 bytes to dest, always adds a terminating null byte, and does not pad the destination with (further) null bytes. This function fixes some of the problems of str‐ cpy() and strncpy(), but the caller must still handle the possibility of data loss if size is too small. The return value of the function is the length of src, which allows truncation to be easily detected: if the return value is
greater than or equal to size, truncation occurred. If
loss of data matters, the caller must either check the ar‐ guments before the call, or test the function return value. strlcpy() is not present in glibc and is not stan‐ dardized by POSIX, but is available on Linux via the libbsd library.
BUGS
If the destination string of a strcpy() is not large
enough, then anything might happen. Overflowing fixed‐
length string buffers is a favorite cracker technique for taking complete control of the machine. Any time a pro‐ gram reads or copies data into a buffer, the program first needs to check that there’s enough space. This may be un‐ necessary if you can show that overflow is impossible, but be careful: programs can get changed over time, in ways that may make the impossible possible.
You may have thought that the manual pages have never been opinionated before, and that they were strict about containing facts. That's never been true, though. You may or may not agree with the previous non-facts, but that doesn't make them more valid.
Quoted 6 lines
Finally, I really don't think that the the mapping between function x and header <
y.h>, a mapping which I characterized as somewhat arbitrary, is something that the average programmer pays that much attention to. If strncpy or memset is to be found in a header called <string.h>, that doesn't tell us that these functions operate on strings,
That contradicts explicit claims by programmers in CC in this thread, who have complained during code review (some months ago) that if strncpy(3) is in <string.h>, then it must be because it's for copying strings, and that I must thus be wrong rejecting code using it for copying strings.
Quoted 5 lines
any more than ssprintf appearing in
<stdio.h> implies that ssprintf does I/O. So let's put the arguing, and the opinionating, and the educating, somewhere else, and have the man pages document (nay, recommend) precisely the headers that the Standard(s) say are standard.
Have a lovely day!
Alex
Quoted 2 lines
Steve Summit
Signature · 1 line
<https://www.alejandro-colomar.es>
Re: on the irresponsibility of pursuing C language reform
Quoted 3 lines · Alejandro
Quoted 1 line
Certainly, today, strncpy and strncat are the new gets.
This is deeply incorrect.
That was a side point, but to clarify what I meant:
Once upon a time (and still today), it's a reasonable thing to say:
Never use gets. Don't worry if you don't understand the issue, don't worry if you heard someone say there's an obscure circumstance under which it might be useful, just don't ever use it; pretend it doesn't exist.
Today I think it's equally reasonable to say:
Never use strncpy and strncat. Don't worry if you don't understand the issue, don't worry if you heard someone say there's an obscure circumstance under which they might be useful, just don't ever use them; pretend they don't exist.
Though perhaps not strictly true, this is good advice, because it will never lead the average programmer astray.
strncpy is not a "fine function", because nobody is using (or should be using) fixed-width string buffers any more. (See, I can be opinionated, too! :-) )
But we don't need to argue about this. I said "strncpy and strncat are the new gets" to concede a point, to agree that discouraging the use of formerly-acceptable interfaces -- a point that I thought you, and certainly that various people, were trying to make -- might be reasonable, even though it's one I often find myself disagreeing with. But that's an opinion I decided to leave out of my previous message, and I'm not going to go down that road here, either.
Alejandro Colomar
maintainerRe: on the irresponsibility of pursuing C language reform
Hi Steve,
Quoted 17 lines
Date: 2026-08-02 09:45:17-0400
From: Steve Summit <[email protected]>Quoted 3 lines · Alejandro
Quoted 1 line
Certainly, today, strncpy and strncat are the new gets.
This is deeply incorrect.
That was a side point, but to clarify what I meant:
Once upon a time (and still today), it's a reasonable thing to say:
Never use gets. Don't worry if you don't understand the issue, don't worry if you heard someone say there's an obscure circumstance under which it might be useful, just don't ever use it; pretend it doesn't exist.
Quoted 7 lines
Today I think it's equally reasonable to say:
Never use strncpy and strncat. Don't worry if you don't understand the issue, don't worry if you heard someone say there's an obscure circumstance under which they might be useful, just don't ever use them; pretend they don't exist.
This is not equally reasonable. First of all, because there really is an obscure circumstance under which, not only they are useful, but actuall they are the best tool for the job. If you tell users to never ever use them, you're treating users as childs uncapable of understanding the facts. In fact, the documentation should instead document the facts in a way that programmers can understand them and use them appropriately.
Secondly, because this somehow attributes the danger to specific functions, but the danger is in misusing functions. For example, N2349, which standardized memccpy(3), was following this premise: strncpy(3) and strncat(3) are bad, so let's just find anything else; as long as it's not one of those two functions, it should be fine. But because the underlying problem is not --and never has been-- the tools, but the humans that misuse them, we have the irony that memccpy(3) is as dangerous as strncpy(3), and even the paper that proposed it for standardization invokes UB in the example code that is supposed to show how it can be used for string copying.
Quoted 2 lines
Though perhaps not strictly true, this is good advice, because it will never lead the average programmer astray.
No, it's not good advice either. memccpy(3) and N2349 is a counter-example of how even an expert programmer (Martin Sebor) will still be led astray.
Quoted 3 lines
strncpy is not a "fine function", because nobody is using (or should be using) fixed-width string buffers any more. (See, I can be opinionated, too! :-) )
I do use it in new code still today in shadow-utils. I've heard tar(1) also needs that, and a few other places. Admittedly, that's orders of magnitude less than strings.
Quoted 5 lines
But we don't need to argue about this. I said "strncpy and strncat are the new gets" to concede a point, to agree that discouraging the use of formerly-acceptable interfaces -- a point that I thought you, and certainly that various people, were trying to make --
Not exactly; my point is that education must be used to teach users how to correctly use interfaces. I consider all these interfaces perfectly acceptable.
Cheers,
Alex
Quoted 4 lines
might be reasonable, even though it's one
I often find myself disagreeing with. But that's an opinion I decided to leave out of my previous message, and I'm not going to go down that road here, either.
Signature · 1 line
<https://www.alejandro-colomar.es>
Re: on the irresponsibility of pursuing C language reform
Quoted 2 lines · Alejandro Colomar
I do use it in new code still today in shadow-utils. I've heard tar(1) also needs that, and a few other places.
GNU tar proper has not used strncpy since 2018. It generally uses memcpy in the places it formerly used strncpy. Tar's 2018 change worked because the destinations were already zeroed out, so strncpy's zero-fill semantics were unnecessary and indeed a bit slower.
As for strncat, its API is a recipe for confusion and almost nobody remembers how it works. It is a poor design, plain and simple. Although strncpy may have a use or two for obsolete non-string data structures that violate GNU coding guidelines that have been in place since the 1980s, strncat has no such redeeming virtues. The current man page for strncat does readers a misservice by not saying so clearly. In contrast, the glibc manual has reasonably decent warnings to users about how bad strncat is (strncpy/strlcpy/etc. too).
To improve the man pages it should be waayyy higher priority to fix their poor discussion of these truncation functions than to worry about whether the man page mentions <string.h> or some other header.
Alejandro Colomar
maintainerRe: on the irresponsibility of pursuing C language reform
Hi Paul,
Quoted 11 lines
Date: 2026-08-02 14:28:33-0500
From: Paul Eggert <[email protected]>Quoted 2 lines · Alejandro Colomar
I do use it in new code still today in shadow-utils. I've heard tar(1) also needs that, and a few other places.
GNU tar proper has not used strncpy since 2018. It generally uses memcpy in the places it formerly used strncpy. Tar's 2018 change worked because the destinations were already zeroed out, so strncpy's zero-fill semantics were unnecessary and indeed a bit slower.
Ok; thanks! In shadow-utils we still need it, though.
Quoted 1 line
As for strncat, its API is a recipe for confusion
The semantics are okay. 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)
It's weird that there's no cpy version of it, though, but this is solved with the usual strcpy(p,"") as first argument.
And the name is certainly bad in context, although an appropriate name would be much more verbose: strcatfrommem(). Maybe we can live with the name strncat(3).
Quoted 2 lines
and almost nobody
remembers how it works.
This is true, and in part, it's because of bad teaching. The fact that GCC's diagnostics recommend bogus usage don't help. I think having it in <memory.h> could help understand it and remember it.
Quoted 1 line
It is a poor design, plain and simple.
There's a need for taking a nonstring (i.e., a fixed-width null-padded buffer, or a substring) and append it to a string. strncat(3) is good for that use case.
Quoted 2 lines
Although
strncpy may have a use or two for obsolete non-string data structures that
Substrings are still necessary. If you want to copy the leading part of a string until a given length, and append it to an existing string, you need strncat(3). I guess this doesn't violate any guidelines.
For this use, in some sense, it's similar to memccpy(3). You don't use it all the time, but when you need it, it's useful.
Quoted 3 lines
violate GNU coding guidelines that have been in place since the 1980s, strncat has no such redeeming virtues. The current man page for strncat does readers a misservice by not saying so clearly.
I disagree that strncat(3) is dead, and will not document it as such.
Moving it to <memory.h> would signal that it's something less appropriate for usual code using strings.
Quoted 3 lines
In contrast, the glibc manual
has reasonably decent warnings to users about how bad strncat is (strncpy/strlcpy/etc. too).
Let's review that.
5.5 Concatenating Strings
...
Programmers using the strcat or wcscat functions (or the strlcat, strncat and wcsncat functions
defined in a later section, for that matter)
can easily be recognized as lazy and reckless.
Lazy can be a virtue, IMO. I wouldn't call them reckless. If they know the prefix string is controlled and small, using the cat functions can be wise: you don't waste much performance, and instead get a simple program. Plan9's strecpy(2) is certainly faster, and doesn't add much complexity, but it still adds a little bit of complexity, so it can sometimes make sense to keep the source simple, at the expense of a few cycles.
In almost all situations the
lengths of the participating strings are known (it better should be
since how can one otherwise ensure
the allocated size of the buffer is sufficient?)
You may know an upper bound without caring about the exact value. Yes, most of the time you know it, but I wouldn't dismiss those times where you don't know (or, for simplicity, you don't want to know).
Or at least,
one could know them if one keeps track of the results of the various function calls.
Indeed, but simplicity might call for not doing this. The compiler can do it for us.
But then it is very inefficient to use strcat/wcscat.
The compiler can do it for us. Correct simple code is better than fast code; and correct code can be optimized by compilers. Since, as you said, the length is easy to find if you keep track of the return values --and the compiler can keep track of them--, then it's a case for improving optimizers.
A lot of time is wasted
finding the end of the destination string
so that the actual copying can start.
...
Whenever a programmer feels the need to use strcat she or he should think twice and look through the program to see whether the code cannot be rewritten
to take advantage of already calculated results.
As said, give me a better compiler, and I'll give you a faster program.
The related functions strlcat, strncat, wcscat and wcsncat are almost always unnecessary, too.
Again:
it is almost always unnecessary to use functions like strcat.
Again, I don't agree.
--- 5.6 Truncating Strings while Copying ... Function: char * strncat (char *restrict to, const char *restrict from, size_t size)
strncat(3) does *not* truncate its input. It copies exactly as many bytes as the source nonstring contains (identified by the pointer and size), unless the source nonstring is shorter, of course, in which case, it's not truncation. It doesn't belong in this section. This is part of the reason why it's misunderstood and misremembered by people: nobody explained it correctly to them.
...
This function is like strcat except that not more than size bytes from from are appended to the end of to, and from need not be null-terminated.
This is pretty much saying that a cat is similar to a fish, except that the cat doesn't live in the sea, and it is a mammal.
A single null byte is also always
appended to to, so the total allocated size of to must be at least size + 1 bytes longer than its initial length.
This is good advice, but not precise wording. If the source nonstring is shorter than its reported size, then the total allocated size need not be so large. Of course, it's good advice that the size is always enough for the worst case, but the wording doesn't seem to be clear that this is only advice, and not a requirement.
The strncat function could be implemented like this:
char *
strncat (char *to, const char *from, size_t size)
{
size_t len = strlen (to);
memcpy (to + len, from, strnlen (from, size));
to[len + strnlen (from, size)] = '\0';
return to;
}This one might be faster and shorter (thanks to Mark for teaching me this):
{
if (memccpy(to + strlen(to), from, '\0', size) == NULL)
strcpy(&to[strlen(to) + size], "");
return to;
}
...
As a companion to strncpy, strncat was designed for now-rarely-used arrays consisting of non-null bytes followed by zero or more null bytes.
But it also works for substrings. If you want to copy a prefix from a string into a new string, strncat(3) --or the dup versions, strndup[a](3)-- help.
However, As noted below, this function is generally a poor choice for processing strings.
Yes, it's a poor choice for handling strings. By moving it to <memory.h>, we signal that it's not for handling strings.
Also, this function has significant performance issues. See Concatenating Strings.
Those are a problem of the optimizer, not of the programmer.
...
Because these functions can abruptly truncate strings or wide strings, they are generally poor choices for processing them. When copying or concatening multibyte strings, they can truncate within a multibyte character so that the result is not a valid multibyte string. When combining or concatenating multibyte or wide strings, they may truncate the output after a combining character, resulting in a corrupted grapheme. They can cause bugs even when processing single-byte strings: for example, when calculating an ASCII-only user name, a truncated name can identify the wrong user.
strncat(3) does not truncate its input, and thus this doesn't tell much about it. It rather compounds on the historic misunderstanding of the function.
Quoted 1 line
To improve the man pages it should be waayyy higher priority
We don't need to prioritize. I have plenty of time to address both issues. While I wrote string_copying(7) for clarifying what strncat(3) is and is not (alongside all the other string-copying functions). I need to revise that page, since I've learnt a lot since I wrote it. I also need to add at least some paragraph in CAVEATS in strncat(3), since readers might not find the other page at all --even if it's in SEE ALSO--.
I'll address all of these.
Quoted 2 lines
to fix their
poor discussion of these truncation functions
That's a wrong categorization of this function. strncat(3) has nothing to do with truncation (as said above).
Quoted 2 lines
than to worry about whether
the man page mentions <string.h> or some other header.
Have a lovely night!
Alex
Signature · 1 line
<https://www.alejandro-colomar.es>
Re: the Linux man-pages as an educational tool
In reply to Alejandro ColomarQuoted 7 lines · Alejandro Colomar
The original implementation in glibc would have been con‐ forming to C99. However, and ironically, trying to comply with C99 before the standard was released, glibc changed its behavior in glibc 2.1.1 into something that ended up not conforming to the final C99 specification (but this is debated, as the wording of the standard seems self‐contra‐ dicting).
Well, this was a period when glibc was driven by personal preferences of
one particular maintainer, so I don't think it is a good example in this discussion. What problem are you trying to fix anyway, what's wrong with using <string.h> for the APIs in question?
Maciej
Alejandro Colomar
maintainerRe: the Linux man-pages as an educational tool
Hi Maciej,
Quoted 5 lines
Date: 2026-08-02 22:23:36+0100
From: "Maciej W. Rozycki" <[email protected]>What problem are you trying to fix anyway, what's wrong with using <
string.h> for the APIs in question?
Programmers misunderstand these functions (some more than others), and think they are appropriate for handling strings in ways that they are inappropriate.
If <string.h> was described as providing functions that exclusively handle strings, then programmers that only need to handle strings would naturally self-limit to functions from this header file.
Those programmers that need more niche memory functions --maybe because they need to handle a substring, or maybe because they need to handle a utmp(5) fixed-width null-padded character array-- can resort to <memory.h>, but that comes with the implied warning that those functions are not the simple interfaces that <string.h> probides; they are
sharper: you can do more with them, but you need to be more careful.
Most programmers can live in the safe bubble of <string.h>: those functions always require a string as input, and always provide a string as output. Plain and simple. It's difficult to write bugs when using those.
That's the rationale.
Have a lovely night!
Alex
Quoted 2 lines
Maciej
Signature · 1 line
<https://www.alejandro-colomar.es>
Re: the Linux man-pages as an educational tool
Quoted 25 lines · Alejandro Colomar
[[PGP Signed Part:No public key for EB89995CC290C2A9 created at 2026-08-02T23:34:34+0200 using RSA]] Hi Maciej,
Quoted 5 lines
Date: 2026-08-02 22:23:36+0100
From: "Maciej W. Rozycki" <[email protected]>What problem are you trying to fix anyway, what's wrong with using <
string.h> for the APIs in question?Programmers misunderstand these functions (some more than others), and think they are appropriate for handling strings in ways that they are inappropriate.
If <
string.h> was described as providing functions that exclusively handle strings, then programmers that only need to handle strings would naturally self-limit to functions from this header file.Those programmers that need more niche memory functions --maybe because they need to handle a substring, or maybe because they need to handle a utmp(5) fixed-width null-padded character array-- can resort to <
memory.h>, but that comes with the implied warning that those functions are not the simple interfaces that <string.h> probides; they are sharper: you can do more with them, but you need to be more careful.
Quoted 6 lines
Most programmers can live in the safe bubble of <
string.h>: those functions always require a string as input, and always provide a string as output. Plain and simple. It's difficult to write bugs when using those.That's the rationale.
I do not follow.
C has no namespaces, let alone qualified imports.
The name of a header providing some function is thus inconsequential.
Indeed, these functions are provided by many headers outside of these two (by accident most often, but sometimes intentionally).
No programmer is able to safely use any C function until they read its documentation.
This goes doubly so for functions operating on bit soup, like mem* and str*.
Signature · 1 line
Arsen Arsenović
Re: the Linux man-pages as an educational tool
Quoted 11 lines · Arsen Arsenović
Quoted 6 lines · Alejandro Colomar
Most programmers can live in the safe bubble of <
string.h>: those functions always require a string as input, and always provide a string as output. Plain and simple. It's difficult to write bugs when using those.That's the rationale.
I do not follow.
C has no namespaces, let alone qualified imports.
That's true.
Quoted 1 line
The name of a header providing some function is thus inconsequential.
Then why not have one official big header file for the whole standard?
#include <stdlibc.h>
When you answer that to your own satisfaction, I suspect you'll have little trouble following Alex's argument.
...which doesn't mean you'll agree with it.
Regards,
Branden
Re: the Linux man-pages as an educational tool
Quoted 17 lines · G. Branden Robinson
Quoted 11 lines · Arsen Arsenović
Quoted 6 lines · Alejandro Colomar
Most programmers can live in the safe bubble of <
string.h>: those functions always require a string as input, and always provide a string as output. Plain and simple. It's difficult to write bugs when using those.That's the rationale.
I do not follow.
C has no namespaces, let alone qualified imports.
That's true.
Quoted 1 line
The name of a header providing some function is thus inconsequential.
Quoted 8 lines
Then why not have one official big header file for the whole standard?
#include <
stdlibc.h>When you answer that to your own satisfaction, I suspect you'll have little trouble following Alex's argument.
...which doesn't mean you'll agree with it.
Plan 9 did this but with "#include <libc.h>" and it seems to have worked fine.
I can't help but wonder of what happens in WG 14 rejects this controversial, as obvious by this thread, change. Will the man-pages changes be reverted? Or will we slowly watch them document personal preferences instead of existing standards? After seeing weekly threads about the prototype changes, I don't think it is an unreasonable concern.
Collin
Alejandro Colomar
maintainerRe: the Linux man-pages as an educational tool
In reply to G. Branden RobinsonHi Branden,
Quoted 16 lines
Date: 2026-08-02 18:10:58-0500
From: "G. Branden Robinson" <[email protected]>Quoted 11 lines · Arsen Arsenović
Quoted 6 lines · Alejandro Colomar
Most programmers can live in the safe bubble of <
string.h>: those functions always require a string as input, and always provide a string as output. Plain and simple. It's difficult to write bugs when using those.That's the rationale.
I do not follow.
C has no namespaces, let alone qualified imports.
Quoted 7 lines
That's true.
Quoted 1 line
The name of a header providing some function is thus inconsequential.
Then why not have one official big header file for the whole standard?
#include <
stdlibc.h>
Heh, curious thing: Plan9 did exactly this (actually, two headers). :)
#include <u.h> #include <libc.h>
Not that I support that idea, of course.
Quoted 3 lines
When you answer that to your own satisfaction, I suspect you'll have little trouble following Alex's argument.
Indeed. Thanks! You've replied in less words than I would have, and were more clear than I would have been.
Quoted 4 lines
...which doesn't mean you'll agree with it.
Regards,
Branden
Have a lovely night!
Alex
Signature · 1 line
<https://www.alejandro-colomar.es>
Alejandro Colomar
maintainerRe: the Linux man-pages as an educational tool
In reply to Collin FunkHi Collin,
Quoted 3 lines
Date: 2026-08-02 16:27:21-0700
From: Collin Funk <[email protected]>
[...]
Quoted 5 lines
I can't help but wonder of what happens in WG 14 rejects this controversial, as obvious by this thread, change. Will the man-pages changes be reverted? Or will we slowly watch them document personal preferences instead of existing standards?
This patch set is quite independent of the standard. It documents a header file that has been provided since forever in glibc and most other POSIX-ish systems, so changes to the standard are unlikely to have any effects. I've clarified this extensively. If you want to discourage me from applying the change, you should rather bring up technical reasons.
This passive-aggressive message is not something that will have the desired effects you could possibly reach with technical arguments.
Have a lovely night, please!
Alex
Quoted 6 lines
After seeing weekly threads
about the prototype changes, I don't think it is an unreasonable concern.Collin
Signature · 1 line
<https://www.alejandro-colomar.es>
Alejandro Colomar
maintainerRe: the Linux man-pages as an educational tool
Quoted 16 lines
Date: 2026-08-03 01:37:30+0200
From: Alejandro Colomar <[email protected]>Hi Collin,
Quoted 3 lines
Date: 2026-08-02 16:27:21-0700
From: Collin Funk <[email protected]>[...]
Quoted 7 lines
I can't help but wonder of what happens in WG 14 rejects this controversial, as obvious by this thread, change. Will the man-pages changes be reverted?
Or will we slowly watch them document personal
preferences instead of existing standards?
BTW, as I showed in another subthread, strncpy(3) did contain opinionated comments well before I was involved. If you're really going to accuse me of that, better make sure you get the history right.
Cheers,
Alex
Quoted 23 lines
This patch set is quite independent of the standard. It documents a header file that has been provided since forever in glibc and most other POSIX-ish systems, so changes to the standard are unlikely to have any effects. I've clarified this extensively. If you want to discourage me from applying the change, you should rather bring up technical reasons.
This passive-aggressive message is not something that will have the desired effects you could possibly reach with technical arguments.
Have a lovely night, please!
AlexQuoted 6 lines
After seeing weekly threads
about the prototype changes, I don't think it is an unreasonable concern.Collin
Signature · 1 line
<https://www.alejandro-colomar.es>
Signature · 1 line
<https://www.alejandro-colomar.es>
Alejandro Colomar
maintainerRe: the Linux man-pages as an educational tool
Quoted 17 lines
Date: 2026-08-03 01:41:39+0200
From: Alejandro Colomar <[email protected]>Quoted 13 lines
Date: 2026-08-03 01:37:30+0200
From: Alejandro Colomar <[email protected]>Hi Collin,
Quoted 3 lines
Date: 2026-08-02 16:27:21-0700
From: Collin Funk <[email protected]>[...]
Quoted 4 lines
I can't help but wonder of what happens in WG 14 rejects this controversial, as obvious by this thread, change. Will the man-pages changes be reverted?
Quoted 6 lines
Quoted 2 lines
Quoted 2 lines
Or will we slowly watch them document personal
preferences instead of existing standards?BTW, as I showed in another subthread, strncpy(3) did contain opinionated comments well before I was involved. If you're really going to accuse me of that, better make sure you get the history right.
Oh, and while at it, please also read my review of glibc's own opinionated and bogus documentation about string truncation.
Cheers,
Alex
Quoted 33 lines
Cheers,
AlexQuoted 23 lines
This patch set is quite independent of the standard. It documents a header file that has been provided since forever in glibc and most other POSIX-ish systems, so changes to the standard are unlikely to have any effects. I've clarified this extensively. If you want to discourage me from applying the change, you should rather bring up technical reasons.
This passive-aggressive message is not something that will have the desired effects you could possibly reach with technical arguments.
Have a lovely night, please!
AlexQuoted 6 lines
After seeing weekly threads
about the prototype changes, I don't think it is an unreasonable concern.Collin
Signature · 1 line
<https://www.alejandro-colomar.es>Signature · 1 line
<https://www.alejandro-colomar.es>
Signature · 1 line
<https://www.alejandro-colomar.es>
Alejandro Colomar
maintainerRe: proposed revision to memory.h(3head)
In reply to Alejandro Colomar[CC trimmed]
Hi Branden,
Quoted 6 lines
Date: 2026-08-02 02:27:44+0200
From: Alejandro Colomar <[email protected]>Quoted 3 lines
Date: 2026-08-01 18:53:32-0500
From: "G. Branden Robinson" <[email protected]>
[...]
Quoted 7 lines
Quoted 3 lines
If you like the foregoing, consider it:
Signed-off-by G. Branden Robinson <[email protected]>I'll probably modify it and note it as
Suggested-by: ...
The final memory.h(3head) manual page is here. It contains a mix of your text and Keith's text.
memory.h(3head) memory.h(3head) NAME memory.h - memory operations LIBRARY Standard C library (libc, -lc) SYNOPSIS #include <memory.h> DESCRIPTION Write bzero(3) memset(3) Copy memmove(3) memcpy(3) mempcpy(3) memccpy(3) strncpy(3) Catenate strncat(3) Duplicate strndup(3) strndupa(3) Compare memcmp(3) strncmp(3) strncasecmp(3) Search memchr(3) memrchr(3) memmem(3) STANDARDS BSD. These functions are also provided in <string.h>, as speci‐ fied by ISO C. This is a historic mistake maintained for compatibility reasons. Don’t let that fool you; these functions don’t necessarily operate on strings. HISTORY SVr1, 4.3BSD. System V (1983) introduced an initial set of mem* func‐ tions in a <memory.h> header file. 4.3BSD (1986) adopted them. C89 didn’t standardize this header file (without providing any motivation or mentions in the documented rationale), and instead crammed all these functions in <string.h>, re‐ sulting in confusing programmers about the real purpose of these functions. Most C libraries, including the BSDs, glibc, and musl, provide <memory.h>. Illumos and gnulib don’t provide it, though, and instead use <string.h>. SEE ALSO string(3), string_copying(7) Linux man‐pages 6.18‐18... 2026‐08‐03 memory.h(3head)
You can already get it through git, so if you want to make any specific changes, please send a patch.
The specific pages (e.g., memcpy(3)) have also been updated. I believe the pages now reflect carefully both what the standard says, and the more reasonable include, while also clearly pointing to this page where the full story is detailed, for those who wonder, so that they don't have to wonder and ask.
A sample here:
SYNOPSIS #include <memory.h> // See STANDARDS void *memcpy(size_t n; void dest[restrict n], const void src[restrict n], size_t n); STANDARDS C11, POSIX.1‐2008. ISO C and POSIX declare this function in <string.h>; see memory.h(3head).
The commit message attributes the text to both of you.
commit 44d6d3bbace4c5a459efb181bcd264b93a655698
Author: Alejandro Colomar <[email protected]>
Date: 2026-08-02 01:20:46 +0200
man/man3head/memory.h.3: STANDARDS, HISTORY: Document some history about <string.h> and <memory.h>
This text is an adaptation of text suggested by Keith and Branden.
Have a lovely night!
Alex
Signature · 1 line
<https://www.alejandro-colomar.es>
Alejandro Colomar
maintainerRe: the Linux man-pages as an educational tool
In reply to Alejandro ColomarQuoted 23 lines
Date: 2026-08-03 01:43:01+0200
From: Alejandro Colomar <[email protected]>Quoted 20 lines
Date: 2026-08-03 01:41:39+0200
From: Alejandro Colomar <[email protected]>Quoted 16 lines
Date: 2026-08-03 01:37:30+0200
From: Alejandro Colomar <[email protected]>Hi Collin,
Quoted 3 lines
Date: 2026-08-02 16:27:21-0700
From: Collin Funk <[email protected]>[...]
Quoted 7 lines
I can't help but wonder of what happens in WG 14 rejects this controversial, as obvious by this thread, change. Will the man-pages changes be reverted?
Or will we slowly watch them document personal
preferences instead of existing standards?
Quoted 6 lines
Quoted 3 lines
BTW, as I showed in another subthread, strncpy(3) did contain opinionated comments well before I was involved. If you're really going to accuse me of that, better make sure you get the history right.
Oh, and while at it, please also read my review of glibc's own opinionated and bogus documentation about string truncation.
<https://www.biblegateway.com/passage/?search=Matthew%207:3-5&version=NIV>
Signature · 1 line
<https://www.alejandro-colomar.es>
Re: the Linux man-pages as an educational tool
In reply to Alejandro ColomarHi Alex,
Quoted 9 lines · Alejandro Colomar
Quoted 9 lines
Quoted 8 lines
Quoted 8 lines
Date: 2026-08-02 16:27:21-0700
From: Collin Funk <[email protected]>
I can't help but wonder of what happens in WG 14 rejects this controversial, as obvious by this thread, change. Will the man-pages changes be reverted?Or will we slowly watch them document personal
preferences instead of existing standards?
Quoted 7 lines
Quoted 4 lines
BTW, as I showed in another subthread, strncpy(3) did contain opinionated comments well before I was involved. If you're really going to accuse me of that, better make sure you get the history right.
Oh, and while at it, please also read my review of glibc's own opinionated and bogus documentation about string truncation.
I don't think this rhetorical tactic is a sound one. You are implying that because Collin (and perhaps others) are not on record as having already consistently opposed editorializing in the glibc manual, or in the Linux man-pages prior to your stewardship, that they are hypocrites.
First, that's not necessarily true. Who's read every word of either work? Who had already done so 5, 10, or 20 years ago?
A charge of hypocrisy can only stick well if you can establish that your interlocutors _endorsed_ the editorializing contemporaneously when it was done by someone else, but are refusing to endorse yours.
But there are more fundamental reasons to conduct this struggle on different grounds, which are that (1) people get to change their minds; and (2) people get to raise defects even if they are old ones.
Thus, if you feel justified in "relitigating", in Joseph's term, the ANSI C Committee's decision in the late 1980s to scotch the memory.h header file, then Collin gets to "relitigate" past editorializing by (I guess?) Michael Kerrisk in the Linux man-pages, or by the glibc authors in their Texinfo manual.
Thus, here you have handed Collin an easy annulment of your point: he can simply say, "well I object to those, too".
Every generation of engineers bears a responsibility to remake the world anew. That which endures does so because its quality is re-tested and re-proved by successive cohorts of humans growing up and running straight at it with their freshly trained minds and novel phenomena of recent invention. When an artifact persists because it's protected from the bratty young philistines by older people who, as William F. Buckley put it, stand athwart history and yell "stop!", it fails to prove its continued utility: it stops being an engineered product and becomes an antiquarian one.
Regards,
Branden
Re: on the irresponsibility of pursuing C language reform
In reply to Alejandro ColomarQuoted 5 lines · Alejandro Colomar
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.
Re: the Linux man-pages as an educational tool... and a bit about C.
In reply to Alejandro ColomarHi Alex,
I want to start by saying, that I think your motivation is crystal clear to any objective observer. And you are perfectly right!
Has anybody denied that those functions don't operate on strings? They don't even know what is the '\0' byte so they don't care about it at all. They operate on the memory region and they do it unmercifully.
Alex, there isn't any kind of mercy in the environment we breath. This is a crucial point to realize.
Now, it doesn't really/really matters which is the right header. Of course it is a header that exposes those functions. It isn't of course <string.h> but again it doesn't really matters. It could be matter if [g]libc.so was splitted in myriads of libraries, and the programmer [-l]inked with the corresponded library. This is not the case here. As others have been said you could just include <[g]libc.h> and been done with that.
Now, while you are perfectly right in principle, what it matters is exactly what are you doing! Recording the CAVEATS, mentioning alternatives, exposing deficiencies, etc. In other words being honest with what you are doing. And you are and this is impressive and you deserve appreciation.
Man pages and without a second thought is the most valuable resource for any C programmer, you don't even want to think C programming without them! My opinion is that they are very well thought and constructed, with the usual wisdom of our ancestors, without bells and whistles and undoubtedly one of our precious jewels.
Alex:
They matter about the standards, please don't forget that. No matter if the standard is right or wrong, this is what we have. Libc'es and compilers are following them. That is not to say that we have to surrender and obey to them as the ultimate truth, when it clearly is not. We still have to give our best to fight for the evolution. But fighting for the header is a loosing battle.
Others:
And while we all love tersenes and compactness, I strongly believe that they are also an educational tool. There is still a room for this. In my opinion this is also a fair objective by Alex, so please encourage him, as it is for our own good also and we've to feel lucky we've him in this position. Someone is getting really serious with his role! And this is extraordinary in our current time.
But and to be a bit cruel here. Does it really matters? Are going to be new programmers? Who we'll taught?
At this point and generally speaking for our current environment and specifically about C.
The C programming language it was the cornerstone of our programming universe.
But, today we live in the kindgom of Rust!
Coreutils were written in Rust and i think ubuntu adopted them. A C compiler has been written in Rust. Bun is written in Rust. Claude writes Rust!
Given those facts, programmers will be just reviewers! But you are some of the best ever born programmers, and you should perfectly understand that:
How on earth a reviewer can understand the mistake, if she never codes? And especially Rust which is zillion of times more complicated than C?
So in absence of logic in our world, C has an incalculable important role to play in time (if of course we'll be blessed with time).
As a song with that same name says:
It takes an ocean of trust in the kingdom of rust...
So even if we paint a wall in the desert, and when we finish a car runs fast and sand destroys the fine painting, there is no other thing to do than to repaint the wall.
Given that we all have to ask by Alex, to continue with what he is doing, as what he is doing is doing it with respect, and today this is precious.
Have a good afternoon,
p.s., i'm rather uneducated. But I started learn C in my 52 and I wrote a libc. I believe that the standard should open some bits the horizons, and be more open to higher abstractions, e.g.,
A copy/read/write/rm/rename file/dir (a good part of coreutils functionality) can be part of the standard. C is about algorithms. If an algorithm works once in C, it will work forever. If the C community consentrates to write all the kind of algorithms with care and love) C will have a role. Otherwise we should be prepared for the inevitable.
Re: the Linux man-pages as an educational tool
In reply to G. Branden RobinsonQuoted 10 lines · G. Branden Robinson
Quoted 1 line
The name of a header providing some function is thus inconsequential.
Then why not have one official big header file for the whole standard?
#include <
stdlibc.h>When you answer that to your own satisfaction, I suspect you'll have little trouble following Alex's argument.
...which doesn't mean you'll agree with it.
The only reason I can imagine for not having One Big Header in 2026 is the same reason why I wouldn't make the change Alex is proposing:
because someone already chose to create many headers and changing it would mean shuffling lots of code around for no gain.
I imagine that, at some point, the amount of time that it would take to read and parse such a header would've been a problem also. Perhaps that inspired the fragmentation. Perhaps not.
I do not know, I didn't do the historiography.
I do know that splitting an extremely widely used header (291,660 matches on Debian codesearch) to replace it with one used far less widely (11,459 matches on that same codesearch, some of which mention portability concerns as the motivation for including memory.h, and I suspect most of which also have an include of string.h in the same file, but I did not verify this) only means that people include both, perhaps conditionally, while seeing no changes outside of the preamble of their source files.
Signature · 1 line
Arsen Arsenović
Alejandro Colomar
maintainerRe: on the irresponsibility of pursuing C language reform
In reply to Paul EggertHi Paul,
Quoted 4 lines
Date: 2026-08-02 22:28:00-0500
From: Paul Eggert <[email protected]>On 8/2/26 15:31, Alejandro Colomar wrote:
Quoted 8 lines
Quoted 5 lines
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,
That can be solved with a local variable. I didn't worry about it, because I don't pass n++ to this thing.
Quoted 2 lines
it overallocates stack space when
strnlen (s, n) < n,
True; I agree that for glibc it makes sense to implement it with memcpy(3). However, for code that's not in a public library --and thus can afford to be wasteful--, and must implement strndupa(3) to workaround the fact that musl doesn't provide it, then I think the simplicity of the strncat(3)-using implementation is worth it.
Quoted 1 line
it obviously has undefined behavior when n ==
SIZE_MAX,
That's also true of n==456789. Anything not trivially small is already UB with alloca(3).
Quoted 2 lines
and it less obviously has undefined behavior because it uses alloca as the argument of a function call.)
Is this still an issue? I thought we were past that limitation, but I was actually concerned when I wrote that code.
The manual page does warn about this:
On many systems alloca() cannot be used inside the list of arguments of a function call, because the stack space re‐ served by alloca() would appear on the stack in the middle of the space for the function arguments.
But since it happens to work in all modern systems I've used, I thought this was probably a thing of the past. It would be good to be more specific about this. If you know which systems are affected, it'd be interesting if you could send a patch for the alloca(3) manual page.
Quoted 3 lines
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.
Actually, I've just realized that the few uses of strndupa(3) that we had in shadow-utils disappeared when we removed the logoutd(8) program in the latest release; thus, we can get rid of our strndupa(3) implementation. We still use strndup(3), though.
We still have one direct use of strncat(3) which I've been wondering whether we can get rid of, but every alternative I try seems to be worse than strncat(3).
/*
* is_my_tty -- determine if "tty" is the same TTY stdin is using
*/
static bool
is_my_tty(const char tty[UTX_LINESIZE])
{
char full_tty[STRLEN("/dev/") + UTX_LINESIZE + 1];
char my_tty[countof(full_tty)];
stpcpy(full_tty, "");
if (tty[0] != '/')
strcpy (full_tty, "/dev/");
strncat(full_tty, tty, UTX_LINESIZE);
if (ttyname_ra(STDIN_FILENO, my_tty) != 0) {
(void) puts (_("Unable to determine your tty name."));
exit (EXIT_FAILURE);
}
return streq(full_tty, my_tty);
}If you think this could be improved with something else, it'd be interesting to hear some advice.
Quoted 3 lines
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),
Thanks!
Quoted 6 lines
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,
I'm not so sure about the correctness of this claim. I'd be interested in learning more about its design, if anyone here knows about it.
Here's what I can read in the V7 sources:
alx@devuan:~/src/unix/unix/v7$ grep -rn 'strncat('
usr/src/cmd/dumpdir.c:153: strncat(prefix, dir.d_name, sizeof(dir.d_name));
usr/src/cmd/login.c:107: strncat(homedir, pwd->pw_dir, sizeof(homedir)-6);
usr/src/libc/gen/strncat.c:8:strncat(s1, s2, n)
usr/man/man3/string.3:9:.B char *strncat(s1, s2, n)There are exactly two calls in V7.
The dumpdir.c call is a perfect example of copying a nonstring (a fixed-size null-padded character array, in this case) into a string *without* truncation.
The login.c call indeed seems to be a use for truncation.
These are two very different uses, and it'd be interesting which one came first, and why the other one was used later.
Quoted 3 lines
something that goes against the GNU
programming guidelines, and something that programmers should be warned against.
I agree. I don't think the current documentation does warn against that use correctly, though.
Have a lovely day!
Alex
Signature · 1 line
<https://www.alejandro-colomar.es>
Alejandro Colomar
maintainerRe: the Linux man-pages as an educational tool
In reply to G. Branden RobinsonHi Branden,
Quoted 21 lines
Date: 2026-08-02 21:09:08-0500
From: "G. Branden Robinson" <[email protected]>Quoted 9 lines · Alejandro Colomar
Quoted 9 lines
Quoted 8 lines
Quoted 8 lines
Date: 2026-08-02 16:27:21-0700
From: Collin Funk <[email protected]>
I can't help but wonder of what happens in WG 14 rejects this controversial, as obvious by this thread, change. Will the man-pages changes be reverted?Or will we slowly watch them document personal
preferences instead of existing standards?Quoted 7 lines
Quoted 4 lines
BTW, as I showed in another subthread, strncpy(3) did contain opinionated comments well before I was involved. If you're really going to accuse me of that, better make sure you get the history right.
Oh, and while at it, please also read my review of glibc's own opinionated and bogus documentation about string truncation.
Quoted 7 lines
I don't think this rhetorical tactic is a sound one. You are implying that because Collin (and perhaps others) are not on record as having already consistently opposed editorializing in the glibc manual, or in the Linux man-pages prior to your stewardship, that they are hypocrites.
First, that's not necessarily true. Who's read every word of either work? Who had already done so 5, 10, or 20 years ago?
He doesn't need to have read every word of the glibc manual, but this precise text he could have read it, because it was mentioned by Paul in this thread (different subthread) prior (19:28 UTC) to his message, and reviewed by me also prior (20:31 UTC) to his message (23:27 UTC).
Date: Sun, 2 Aug 2026 14:28:33 -0500 From: Paul Eggert <[email protected]> Message-ID: <[email protected]> Date: Sun, 2 Aug 2026 22:31:59 +0200 From: Alejandro Colomar <[email protected]> Message-ID: <am-eAGL6OWqP9Yah@devuan> Date: Sun, 02 Aug 2026 16:27:21 -0700 From: Collin Funk <[email protected]> Message-ID: <[email protected]>
Also relevant is the fact that he accused me of "slowly" documenting "personal preferences". His wording implies that it wasn't there before. Maybe I misunderstood, though. I'd be happy to rectify if I was wrong.
While he didn't need to know whether it was there before, it would be good to make some effort to learn whether that was the case, before making such a serious accusation.
In this specific case, again, the relevant text had been shown by me in this thread (different subthread), prior to (13:17 UTC) his message, and thus again he should have known.
Date: Sun, 2 Aug 2026 15:17:04 +0200 From: Alejandro Colomar <[email protected]> Message-ID: <am8_MfPmud43naU-@devuan>
Quoted 3 lines
A charge of hypocrisy can only stick well if you can establish that your interlocutors _endorsed_ the editorializing contemporaneously when it was done by someone else, but are refusing to endorse yours.
I believe the timestamps above, and the fact that he's been (obviously) aware of this thread, are sufficient for this charge in this case.
I do agree that in general we shouldn't attribute hypocrisy without proof, when it might actually be just lack of information.
Quoted 2 lines
But there are more fundamental reasons to conduct this struggle on different grounds, which are that (1) people get to change their minds;
Oh, indeed; I've done plenty of times, and it's good. I certainly welcome that.
Quoted 7 lines
and (2) people get to raise defects even if they are old ones.
Thus, if you feel justified in "relitigating", in Joseph's term, the ANSI C Committee's decision in the late 1980s to scotch the
memory.hheader file, then Collin gets to "relitigate" past editorializing by (I guess?) Michael Kerrisk in the Linux man-pages, or by the glibc authors in their Texinfo manual.
Certainly.
Quoted 2 lines
Thus, here you have handed Collin an easy annulment of your point: he can simply say, "well I object to those, too".
I'd welcome that as being consistent, and would then apologize, if for some reason he really wasn't aware of the messages whose timestamps are shown above.
If he was aware, then I wouldn't apologize, because the offense and hypocrisy would have happened, but still, I'd welcome a positive change of mind, and leave both my and his words in the past.
Quoted 9 lines
Every generation of engineers bears a responsibility to remake the world anew. That which endures does so because its quality is re-tested and re-proved by successive cohorts of humans growing up and running straight at it with their freshly trained minds and novel phenomena of recent invention. When an artifact persists because it's protected from the bratty young philistines by older people who, as William F. Buckley put it, stand athwart history and yell "stop!", it fails to prove its continued utility: it stops being an engineered product and becomes an antiquarian one.
Have a lovely day!
Alex
Signature · 1 line
<https://www.alejandro-colomar.es>
Re: the Linux man-pages as an educational tool
In reply to Alejandro ColomarQuoted 2 lines · Alejandro Colomar
This is just a case where educating on the current standards is done by
1) documenting at the bottom of the manual what the standard says, and
The standard-compliant #include statement should be documented in the SYNOPSIS, not at the bottom of the man page.
Quoted 2 lines
2) recommending to ignore it because it's bad. When the standards are bad, this is appropriate course.
Which functions are "bad"? It's not up to you (single person) to decide this. Rather, poll among the libc implementors, and if a majority says a function is "bad", then mark it as bad.
That's basically how it went with 'gets': The community realized it is a bad function, then the implementors started to withdraw it.
And even there, look at several implementors, not only at a single one. For instance, NetBSD considers uselocale() to be "bad" and therefore does not implement it. That's a single-implementor opinion, not a majority.
Bruno
Alejandro Colomar
maintainerRe: the Linux man-pages as an educational tool
Hi Bruno,
Quoted 9 lines
Date: 2026-08-03 14:35:06+0200
From: Bruno Haible <[email protected]>Quoted 2 lines · Alejandro Colomar
This is just a case where educating on the current standards is done by
1) documenting at the bottom of the manual what the standard says, andThe standard-compliant #include statement should be documented in the SYNOPSIS, not at the bottom of the man page.
That's an opinion, which I respect, but at the moment, and given the thorough research I've carried out, I disagree with it it.
If you want to know what the standards say, you have available at your disposition the STANDARDS section, and the standards themselves.
The Linux manual pages are not the ISO C manual pages.
Quoted 4 lines
Quoted 2 lines
2) recommending to ignore it because it's bad. When the standards are bad, this is appropriate course.
Which functions are "bad"?
I didn't say any functions are bad (other than gets(3)). I did say the standards are bad. The standard specification of realloc(,0) is bad, for example. The standard #include's and organization of strn*() functions is also bad.
Where did you get the idea that I've claimed that any functions are bad?
Quoted 1 line
It's not up to you (single person) to decide this.
I've done enough research and heard enough parties to conclude this.
Quoted 2 lines
Rather, poll among the libc implementors, and if a majority says a function is "bad", then mark it as bad.
I've polled libc implementors for their technical reasons, I've heard those arguments carefully, analyzed them, and concluded based on that.
I've also heard subjective opinions alongside those technical arguments, and I've also carefully analyzed them, although they carry significantly less weight than the technical arguments, and in some cases, they carry negative weight, as they show that the person that emitted them is not experienced enough about this topic.
With all that information, I've taken a decision.
I haven't marked any functions as bad (contrary to some opinions from libc maintainers), FWIW.
Quoted 2 lines
That's basically how it went with 'gets': The community realized it is a bad function, then the implementors started to withdraw it.
Here's an interesting story about gets(3), which I learnt recently:
The C Committee didn't remove it from ISO C. It was the Austin Group that triggered some unusual process within ISO for overriding the C Committee, and removed it in a secret meeting.
The removal probably wouldn't have been accepted by the C Committee if it had gone through the usual process.
Quoted 3 lines
And even there, look at several implementors, not only at a single one. For instance, NetBSD considers
uselocale()to be "bad" and therefore does not implement it. That's a single-implementor opinion, not a majority.
Have a lovely day!
Alex
Signature · 1 line
<https://www.alejandro-colomar.es>
Re: on the irresponsibility of pursuing C language reform
In reply to Alejandro ColomarQuoted 4 lines · Alejandro Colomar
It's certainly a privileged position. Just like maintainer of GCC, or of Clang, or any other core project of most systems. I acknowledge this, and I believe I've acknowledged this before, implicitly and explicitly.
Subsystem maintainers in glibc may choose to assume consensus for their own changes in that subsystem *in the absence of evidence to the contrary*. If it becomes clear that in fact there is not consensus for such a change, they still need to revert it and go through the community process to figure out what has consensus instead (or if the community is unable to reach consensus, go to a vote of the GNU maintainers for glibc, but such a vote should be very rare); being a subsystem maintainer is just a shortcut and a signal of recognized expertise in that subsystem, not a mechanism to override consensus.
Signature · 2 lines
Joseph S. Myers [email protected]
Re: on the irresponsibility of pursuing C language reform
In reply to Alejandro ColomarQuoted 6 lines · Alejandro Colomar
Joseph was concerned that this documentation would conflict with many documents saying that <
memory.h> is deprecated. Luckily, I've never seen such a document, so we can assume they don't exist (unless people show evidence). I'll dismiss his negative vote, since his technical reasons are incorrect. Also, <memory.h> is undoubtedly more portable than a new <stdmem.h>.
The glibc manual nowhere mentions <memory.h>. That's pretty clear evidence the header is a relic of the days when glibc just took any interface some 1980s Unix had rather than trying to have a cleaner API of more current relevance.
My main concern, in any case, is that man-pages should describe the world as it is, not as you'd like it to be; they should follow, not lead, on any proposed changes; they should promote portable coding practices and using existing standard interfaces in the absence of broad consensus (not just your opinion; not just an opinion based on dismissing all the views against) of a clear technical deficiency in those interfaces; that anyone advocating for an interface change should avoid using man-pages as part of that advocacy, only eventually updating it after the debate has concluded once there is consensus on what the conclusion of the debate was but ensuring the man-pages don't take any one side of the debate before then.
I suggest we need to figure out how to generate man pages from the glibc manual so that people who prefer documentation in that format can have documentation of glibc interfaces that's maintained by a proper consensual process rather than following one person's opinion.
Signature · 2 lines
Joseph S. Myers [email protected]
Alejandro Colomar
maintainerWhen and why realloc(,0) was broken in glibc in 1999
In reply to Maciej W. RozyckiHi Maciej,
Quoted 13 lines
Date: 2026-08-02 22:23:36+0100
From: "Maciej W. Rozycki" <[email protected]>Quoted 7 lines · Alejandro Colomar
The original implementation in glibc would have been con‐ forming to C99. However, and ironically, trying to comply with C99 before the standard was released, glibc changed its behavior in glibc 2.1.1 into something that ended up not conforming to the final C99 specification (but this is debated, as the wording of the standard seems self‐contra‐ dicting).
Quoted 3 lines
Well, this was a period when glibc was driven by personal preferences of
one particular maintainer, so I don't think it is a good example in this discussion.
Just to clarify something about this, to which I didn't reply before:
we can't blame Drepper for this bug.
In this case, there was a discussion in the mailing list, and there was no discrepancy against this change.
<https://sourceware.org/pipermail/libc-alpha/1999-April/000956.html>
It's just a case of a discussion that happened with incomplete information, and which favoured standards conformance over common sense.
In fact, I was surprised when I learnt about this case, because I would have expected Drepper to ignore the standard for being bogus.
Jonathan Larmour correctly noted in that discussion that glibc was not conforming to C89.
<https://sourceware.org/pipermail/libc-alpha/1999-April/002394.html>
This finding from Jonathan should have triggered some more research, but they didn't.
Roland McGrath pointed out his understanding of the (ambiguous) C89 specification, and claimed that it was a bug in glibc (and thus he seems to have been in favour of the "fix" too).
<https://sourceware.org/pipermail/libc-alpha/1999-April/000958.html>
Interestingly, he claimed that it was a recently introduced bug, but as far as I know, the glibc behavior had been unchanged before that.
It seems it was Roland McGrath who pushed for the idea that consistency wasn't paramound, and that standards conformance was.
<https://sourceware.org/pipermail/libc-alpha/1999-April/002398.html>
Then Drepper did that change, and in his head it was consistent.
<https://sourceware.org/pipermail/libc-alpha/1999-April/000963.html>
It clearly isn't consistent, but it's understandable that he didn't see it back then.
Wolfram Gloger seemed to be convinced that Drepper's change was consistent (even if it isn't).
<https://sourceware.org/pipermail/libc-alpha/1999-April/002401.html>
For some reason, nobody in that group analyzed this carefully enough. I guess it was inertia. We can't blame Drepper (alone) for this bug.
Have a lovely day!
Alex
Signature · 1 line
<https://www.alejandro-colomar.es>
Re: the Linux man-pages as an educational tool
In reply to Alejandro ColomarQuoted 12 lines · Alejandro Colomar
Hi Collin,
Quoted 3 lines
Date: 2026-08-02 16:27:21-0700
From: Collin Funk <[email protected]>[...]
Quoted 5 lines
I can't help but wonder of what happens in WG 14 rejects this controversial, as obvious by this thread, change. Will the man-pages changes be reverted? Or will we slowly watch them document personal preferences instead of existing standards?
Quoted 8 lines
This patch set is quite independent of the standard. It documents a header file that has been provided since forever in glibc and most other POSIX-ish systems, so changes to the standard are unlikely to have any effects. I've clarified this extensively. If you want to discourage me from applying the change, you should rather bring up technical reasons.
This passive-aggressive message is not something that will have the desired effects you could possibly reach with technical arguments.
I didn't read it as passive-aggressive, but I will say that I think you've gone a bit hard in the responses to Collin in this subthread, and I think the fact you sent several followup emails to yourself indicates perhaps things got heated in the moment.
I think Collin was making the same conflict of interest point as was raised earlier, just in a different way. You may or may not agree with how he phrased it, and you're free to challenge that, but my reading of your replies is that it went a bit far.
Quoted 11 lines
Have a lovely night, please!
AlexQuoted 6 lines
After seeing weekly threads
about the prototype changes, I don't think it is an unreasonable concern.Collin
sam
Re: the Linux man-pages as an educational tool
In reply to Alejandro ColomarQuoted 28 lines · Alejandro Colomar
Hi Branden,
Quoted 26 lines
Date: 2026-08-02 21:09:08-0500
From: "G. Branden Robinson" <[email protected]>Quoted 9 lines · Alejandro Colomar
Quoted 9 lines
Quoted 8 lines
Quoted 8 lines
Date: 2026-08-02 16:27:21-0700
From: Collin Funk <[email protected]>
I can't help but wonder of what happens in WG 14 rejects this controversial, as obvious by this thread, change. Will the man-pages changes be reverted?Or will we slowly watch them document personal
preferences instead of existing standards?Quoted 7 lines
Quoted 4 lines
BTW, as I showed in another subthread, strncpy(3) did contain opinionated comments well before I was involved. If you're really going to accuse me of that, better make sure you get the history right.
Oh, and while at it, please also read my review of glibc's own opinionated and bogus documentation about string truncation.
I don't think this rhetorical tactic is a sound one. You are implying that because Collin (and perhaps others) are not on record as having already consistently opposed editorializing in the glibc manual, or in the Linux man-pages prior to your stewardship, that they are hypocrites.
Quoted 7 lines
Quoted 2 lines
First, that's not necessarily true. Who's read every word of either work? Who had already done so 5, 10, or 20 years ago?
He doesn't need to have read every word of the glibc manual, but this precise text he could have read it, because it was mentioned by Paul in this thread (different subthread) prior (19:28 UTC) to his message, and reviewed by me also prior (20:31 UTC) to his message (23:27 UTC).
I often reply as I go rather than reading all other emails around that time. I don't think you should assume he read those emails and deliberately neglected their contents.
Quoted 13 lines
Date: Sun, 2 Aug 2026 14:28:33 -0500 From: Paul Eggert <[email protected]> Message-ID: <[email protected]> Date: Sun, 2 Aug 2026 22:31:59 +0200 From: Alejandro Colomar <[email protected]> Message-ID: <am-eAGL6OWqP9Yah@devuan> Date: Sun, 02 Aug 2026 16:27:21 -0700 From: Collin Funk <[email protected]> Message-ID: <[email protected]>
Quoted 4 lines
Also relevant is the fact that he accused me of "slowly" documenting "personal preferences". His wording implies that it wasn't there before. Maybe I misunderstood, though. I'd be happy to rectify if I was wrong.
I think he meant in general?
Quoted 4 lines
While he didn't need to know whether it was there before, it would be good to make some effort to learn whether that was the case, before making such a serious accusation.
I took it to be that you (as you've said yourself) have a different style from Michael and this does involve a more opinionated (you may not call it that) approach. He's commenting on that being unfavourable to him. I didn't think that was contentious, more that you see it as your duty wrt education.
Quoted 4 lines
...
sam
Re: proposed revision to memory.h(3head) (was: on the irresponsibility of pursuing C language reform)
In reply to Alejandro ColomarQuoted 1 line · Alejandro Colomar
I don't know of any copy of SVID Issue 1.
I have a printed copy. It has <memory.h> on pages 208 and 209, with FUTURE DIRECTIONS saying "The declarations in <memory.h> will be moved to <string.h>.". (Likewise in XPG1.)
Quoted 2 lines
I'd be curious to see whether XPG Issue 3 still kept <
memory.h> (but I suspect it won't, since it derives from POSIX.1-1988).
Page 642 of volume 2 lists it as WITHDRAWN, "The declarations in <memory.h> have been moved to <string.h>.".
So there you have explicit statements showing an intentional, planned move.
Signature · 2 lines
Joseph S. Myers [email protected]
Alejandro Colomar
maintainerRe: on the irresponsibility of pursuing C language reform
In reply to Joseph MyersHi Joseph,
Quoted 12 lines
Date: 2026-08-03 13:42:31+0000
From: Joseph Myers <[email protected]>Quoted 6 lines · Alejandro Colomar
Joseph was concerned that this documentation would conflict with many documents saying that <
memory.h> is deprecated. Luckily, I've never seen such a document, so we can assume they don't exist (unless people show evidence). I'll dismiss his negative vote, since his technical reasons are incorrect. Also, <memory.h> is undoubtedly more portable than a new <stdmem.h>.
Quoted 4 lines
The glibc manual nowhere mentions <
memory.h>. That's pretty clear evidence the header is a relic of the days when glibc just took any interface some 1980s Unix had rather than trying to have a cleaner API of more current relevance.
I don't refute that. But relics are sometimes useful and reusable.
Quoted 3 lines
My main concern, in any case, is that man-pages should describe the world as it is, not as you'd like it to be; they should follow, not lead, on any proposed changes;
This has never been true. I believe Michael did a great job maintaining them, and that included promoting some APIs over others, even when that goes against the standards. See below.
Quoted 6 lines
they should promote portable coding practices and using existing standard interfaces in the absence of broad consensus (not just your opinion; not just an opinion based on dismissing all the views against) of a clear technical deficiency in those interfaces; that anyone advocating for an interface change should avoid using man-pages as part of that advocacy,
I'm not using the manual pages as part of advocating for an interface change. I'm advocating for an interface change as a consequence of the research work I've done to improve the manual pages.
Quoted 3 lines
only eventually updating it after the debate has concluded once there is consensus on what the conclusion of the debate was but ensuring the man-pages don't take any one side of the debate before then.
Would you mind expressing your feedback about the fact that str[n]cpy(3) documented the non-standard strlcpy(3), and suggested that it'd be used instead? This is way before POSIX.1-2024 standardized it. In fact, POSIX.1-2008 had explicitly rejected these functions.
commit bb96fc35a3b664ef3959eaefb095608846f89df7 Author: Michael Kerrisk <[email protected]> Date: 2012-07-19 11:29:15 +0200 strcpy.3: NOTES: Add a discussion of strlcpy() Inspired by https://lwn.net/Articles/506530/ Signed-off-by: Michael Kerrisk <[email protected]>
which introduced this text:
$ MANWIDTH=64 diffman-git bb96fc35a3b664ef3959eaefb095608846f89df7 --- bb96fc35a3b664ef3959eaefb095608846f89df7^:man3/strcpy.3 +++ bb96fc35a3b664ef3959eaefb095608846f89df7:man3/strcpy.3 @@ -54,6 +54,14 @@ NOTES to test!) that the size of dest is greater than the length of src, then strcpy() can be used.
+ One valid (and intended) use of strncpy() is to copy a C + string to a fixed‐length buffer while ensuring both that + the buffer is not overflowed and that unused bytes in the + target buffer are zeroed out (perhaps to prevent informa‐ + tion leaks if the buffer is to written to media or trans‐ + mitted to another process via an interprocess communica‐ + tion technique).
+
If there is no terminating null byte in the first n bytes of src, strncpy() produces an unterminated string in dest. Programmers often prevent this mistake by forcing termina‐
@@ -67,6 +75,27 @@ NOTES
formation contained in src is lost in the copying to dest.)
+ Some systems (the BSDs, Solaris, and others) provide the
+ following function:
+
+ size_t strlcpy(char *dest, const char *src, size_t
+ size);
+
+ This function is similar to strncpy(), but it copies at
+ most size-1 bytes to dest, always adds a terminating null
+ byte, and does not pad the target with (further) null
+ bytes. This function fixes some of the problems of str‐
+ cpy() and strncpy(), but the caller must still handle the
+ possibility of data loss if size is too small. The return
+ value of the function is the length of src, which allows
+ truncation to be easily detected: if the return value is
+ greater than or equal to size, truncation occurred. If
+ loss of data matters, the caller must either check the ar‐
+ guments before the call, or test the function return
+ value. strlcpy() is not present in glibc and is not stan‐
+ dardized by POSIX, but is available on Linux via the
+ libbsd library.
+
BUGS
If the destination string of a strcpy() is not large enough, then anything might happen. Overflowing fixed‐
@@ -82,4 +111,4 @@ SEE ALSO
bcopy(3), memccpy(3), memcpy(3), memmove(3), stpcpy(3), stpncpy(3), strdup(3), string(3), wcscpy(3), wcsncpy(3)
-GNU 2012‐07‐18 STRCPY(3)
+GNU 2012‐07‐19 STRCPY(3)
That commit was itself based on the LWN article it metions in the commit message, and it contained a number of comments
<https://lwn.net/Articles/507319/#Comments> that cautioned that strlcpy/cat(3) might not be the best interface, and I'd say there wasn't consensus either back then. There will never be consensus on this topic, I believe.
Yet, some things have to be done. Mistakes may be made when doing this, and they should be eventually addressed. But manual pages should not be a copy of the standards.
If we go back further in time, man-pages-1.0 --the very first release, in 1993-- already documented that gets(3) should never be used. This was certainly to the contrary of the existing standards, and indeed was leading the removal that came later. That page was written by Thomas Koenig. I don't think Thomas was wrong doing that.
Past times often feel better, but that's nostalgia, and often not based on facts.
Quoted 4 lines
I suggest we need to figure out how to generate man pages from the glibc manual so that people who prefer documentation in that format can have documentation of glibc interfaces that's maintained by a proper consensual process rather than following one person's opinion.
The Linux manual pages are not strictly the glibc manual. They also document musl, for example. Also, I believe it's good that it's independent of glibc and GNU. That puts a degree of criticism that is necessary for avoiding endogamy. Let's say it's a separation of powers.
Have a lovely day!
Alex
Signature · 1 line
<https://www.alejandro-colomar.es>
Alejandro Colomar
maintainerRe: the Linux man-pages as an educational tool
In reply to Sam JamesHi Sam,
Quoted 21 lines
Date: 2026-08-03 15:03:30+0100
From: Sam James <[email protected]>Quoted 16 lines · Alejandro Colomar
Quoted 3 lines
Date: 2026-08-02 16:27:21-0700
From: Collin Funk <[email protected]>[...]
Quoted 5 lines
I can't help but wonder of what happens in WG 14 rejects this controversial, as obvious by this thread, change. Will the man-pages changes be reverted? Or will we slowly watch them document personal preferences instead of existing standards?
This patch set is quite independent of the standard. It documents a header file that has been provided since forever in glibc and most other POSIX-ish systems, so changes to the standard are unlikely to have any effects. I've clarified this extensively. If you want to discourage me from applying the change, you should rather bring up technical reasons.
Quoted 4 lines
Quoted 2 lines
This passive-aggressive message is not something that will have the desired effects you could possibly reach with technical arguments.
I didn't read it as passive-aggressive,
I did, and still do.
Quoted 4 lines
but I will say that I think
you've gone a bit hard in the responses to Collin in this subthread, and I think the fact you sent several followup emails to yourself indicates perhaps things got heated in the moment.
Yes, they have. And it was good that a night has happened after that. It had calmed down.
Quoted 4 lines
I think Collin was making the same conflict of interest point as was raised earlier, just in a different way. You may or may not agree with how he phrased it, and you're free to challenge that, but my reading of your replies is that it went a bit far.
Collin went too far.
Have a lovely day!
Alex
Signature · 1 line
<https://www.alejandro-colomar.es>
Alejandro Colomar
maintainerRe: proposed revision to memory.h(3head) (was: on the irresponsibility of pursuing C language reform)
In reply to Joseph MyersHi Joseph,
Quoted 11 lines
Date: 2026-08-03 14:10:30+0000
From: Joseph Myers <[email protected]>Quoted 1 line · Alejandro Colomar
I don't know of any copy of SVID Issue 1.
I have a printed copy. It has <
memory.h> on pages 208 and 209, with FUTURE DIRECTIONS saying "The declarations in <memory.h> will be moved to <string.h>.". (Likewise in XPG1.)
Quoted 8 lines
Quoted 2 lines
I'd be curious to see whether XPG Issue 3 still kept <
memory.h> (but I suspect it won't, since it derives from POSIX.1-1988).Page 642 of volume 2 lists it as WITHDRAWN, "The declarations in <
memory.h> have been moved to <string.h>.".So there you have explicit statements showing an intentional, planned move.
Thanks a lot! I'll change the manual pages to reflect these historic details.
I still think that since those are not mainstream, users shouldn't be confused about the fact that <memory.h> has been obsolete for so long and is now shown in documentation.
But these historic details will certainly change the documentation I wrote. Thanks!
Have a lovely day!
Alex
Signature · 1 line
<https://www.alejandro-colomar.es>
on glibc forking/reclaiming its man pages (was: on the irresponsibility of pursuing C language reform)
In reply to Joseph MyersHi Joseph,
Quoted 4 lines · Joseph Myers
I suggest we need to figure out how to generate man pages from the glibc manual so that people who prefer documentation in that format can have documentation of glibc interfaces that's maintained by a proper consensual process rather than following one person's opinion.
I speculate that Richard Stallman expected that this sort of thing would be soon implemented and accomplished...in 1989. Or earlier.
Official GNU documentation continues to suggest that (Tex)Info shall prevail and that man pages are destined to wither away, as Engels predicted of the State.
https://www.gnu.org/prep/standards/html_node/Man-Pages.html
Speaking from experience as a GNU maintainer and from observation of others, I assess the task you outline as anything but easy. Chet Ramey has been maintaining Bash documentation in parallel man(7) and Texinfo forms for decades.
https://lists.gnu.org/r/coreutils/2026-05/msg00044.html
In groff, I maintain a ~300 page Texinfo manual alongside ~400 pages of man pages. Overlap is only partial; the Texinfo manual focuses much more on specifying the formatter's behavior in exhaustive detail, in about 180 pages of the total length--much more than half when you consider that about 60 pages are given over to indices and the GNU FDL license text. The man pages document groff's preprocessors, output drivers, utilities, wrappers, macro packages, and so forth.
https://www.gnu.org/software/groff/manual/
(groff's Texinfo manual will look much nicer, and additional manuals in PDF format will be available, in a couple of weeks when I release groff 1.25.0 final--knock wood.)
At the same time there _is_ substantial overlap between a few of our man pages and groff's Texinfo manual. You can find comments in the source documents referring to "keeping sync".
I perform such synchronization by hand, and not perfectly.
Even after years of experience doing this, I've found that nailing down the parameters of what would be required to automate such synchronization is tough. Autogeneration of one format from the other would, I think, be a closely related problem.
If the task were easy, someone would have done it by 1990.
If the task were of medium difficulty, I suspect the Pandoc project would have solved it with a Texinfo reader by now.
https://pandoc.org/MANUAL.html
They haven't, so far.
On the bright side, I wager that a domain-specific translator to get from a specific Texinfo manual--likely one that imposed special rules on its maintainers to enable extraction of data necessary for man page production--could be written. The job will demand someone with solid domain expertise in both formats. Better, such people actually exist.
I'm available for consulting work. Do you have budgetary authority?
Or, you know, there are LLM coding agents...
As a third option, we could lower the temperature just a little bit. In an email on project management that I'm still drafting, I implicitly suggest that Alex do the same.
Regards,
Branden
Alejandro Colomar
maintainerRe: the Linux man-pages as an educational tool
In reply to Sam JamesHi Sam,
Quoted 5 lines
Date: 2026-08-03 15:05:36+0100
From: Sam James <[email protected]>Alejandro Colomar <[email protected]> writes:
[...]
Quoted 8 lines
Quoted 4 lines
He doesn't need to have read every word of the glibc manual, but this precise text he could have read it, because it was mentioned by Paul in this thread (different subthread) prior (19:28 UTC) to his message, and reviewed by me also prior (20:31 UTC) to his message (23:27 UTC).
I often reply as I go rather than reading all other emails around that time. I don't think you should assume he read those emails and deliberately neglected their contents.
Me too. But eventually I respond to those other emails, and rectify when that new information conflicts with something I said with incomplete information. So far, Collin didn't rectify.
Quoted 13 lines
Quoted 13 lines
Date: Sun, 2 Aug 2026 14:28:33 -0500 From: Paul Eggert <[email protected]> Message-ID: <[email protected]> Date: Sun, 2 Aug 2026 22:31:59 +0200 From: Alejandro Colomar <[email protected]> Message-ID: <am-eAGL6OWqP9Yah@devuan> Date: Sun, 02 Aug 2026 16:27:21 -0700 From: Collin Funk <[email protected]> Message-ID: <[email protected]>
Quoted 6 lines
Quoted 4 lines
Also relevant is the fact that he accused me of "slowly" documenting "personal preferences". His wording implies that it wasn't there before. Maybe I misunderstood, though. I'd be happy to rectify if I was wrong.
I think he meant in general?
I don't interpret that. I guess he can defend himself and clarify.
Quoted 9 lines
Quoted 3 lines
While he didn't need to know whether it was there before, it would be good to make some effort to learn whether that was the case, before making such a serious accusation.
I took it to be that you (as you've said yourself) have a different style from Michael and this does involve a more opinionated (you may not call it that) approach. He's commenting on that being unfavourable to him. I didn't think that was contentious, more that you see it as your duty wrt education.
I only see my style slightly different than Michael's, but not necessarily in the sense of involving a more opinionated approach. See the other messages where I've shown how Michael had done the exact same thing with strlcpy(3) a long time ago.
On reconsideration, and after researching what Michael really did, I think I was wrong saying we have a different style at all. I believe we've had the same style. We just had different topics of expertise.
Michael has had his own share of opinionated comments in manual pages.
Have a lovely day!
Alex
Signature · 1 line
<https://www.alejandro-colomar.es>
Re: on glibc forking/reclaiming its man pages (was: on the irresponsibility of pursuing C language reform)
In reply to G. Branden RobinsonQuoted 5 lines · G. Branden Robinson
On the bright side, I wager that a domain-specific translator to get from a specific Texinfo manual--likely one that imposed special rules on its maintainers to enable extraction of data necessary for man page production--could be written. The job will demand someone with solid domain expertise in both formats. Better, such people actually exist.
We do in fact have such translation for GCC and binutils; parts of the Texinfo manuals are marked up for extraction with a script texi2pod.pl with the results then going through pod2man (as shipped with perl). (Being intended for converting instructions for invoking a command-line program, rather than documentation for library functions, no doubt significant changes would be needed to be useful for glibc; also, the glibc manual documents lots of things outside of the individual function descriptions, and that information wouldn't end up in such generated man pages because it's not suitably structured to put in them.)
Signature · 2 lines
Joseph S. Myers [email protected]
Re: on glibc forking/reclaiming its man pages (was: on the irresponsibility of pursuing C language reform)
Hi Joseph,
Quoted 9 lines · Joseph Myers
Quoted 6 lines · G. Branden Robinson
On the bright side, I wager that a domain-specific translator to get from a specific Texinfo manual--likely one that imposed special rules on its maintainers to enable extraction of data necessary for man page production--could be written. The job will demand someone with solid domain expertise in both formats. Better, such people actually exist.
Quoted 3 lines
We do in fact have such translation for GCC and binutils; parts of the Texinfo manuals are marked up for extraction with a script texi2pod.pl with the results then going through pod2man (as shipped with perl).
Now that you mention it, that does ring a bell. I probably didn't think of it because you're using POD as an intermediate format. That forecloses some possibilities, but mandoc(1) maintainer Ingo Schwarze and I share the opinion that it is the best-of-breed man(7) generator. I reiterate, though...you give some things up with POD, like tables.
Quoted 3 lines
(Being intended for converting instructions for invoking a command-line program, rather than documentation for library functions, no doubt significant changes would be needed to be useful for glibc;
I agree. Every time I've looked (cursorily) at a problem with this shape, I've thought, "mmmm...tricky", and moved on.
Quoted 4 lines
also, the glibc manual documents lots of things outside of the individual function descriptions, and that information wouldn't end up in such generated man pages because it's not suitably structured to put in them.)
Yes. Every few years someone asks the groff list why we haven't just up and converted our Texinfo manual to man pages yet.
Structure. The biggest impedance mismatch is structure. Steve Summit raised the famous old point about a "reference, not a tutorial", and I don't know if I'll work up the steam to reply to him more fully, but that proves a tough boundary to police.
There are people who will read _only_ man pages and never anything else. Those people release a horde of Hyrum's Law gerbils into your system.
Regards,
Branden
Re: the Linux man-pages as an educational tool
In reply to Alejandro ColomarQuoted 10 lines · Alejandro Colomar
Quoted 3 lines
From: Sam James <[email protected]>
Alejandro Colomar <[email protected]> writes:[...]
Quoted 6 lines
Quoted 5 lines
[Collin Funk] doesn't need to have read every word of the glibc manual, but this precise text he could have read it, because it was mentioned by Paul in this thread (different subthread) prior (19:28 UTC) to his message, and reviewed by me also prior (20:31 UTC) to his message (23:27 UTC).
Quoted 7 lines
Quoted 3 lines
I often reply as I go rather than reading all other emails around that time. I don't think you should assume he read those emails and deliberately neglected their contents.
Me too. But eventually I respond to those other emails, and rectify when that new information conflicts with something I said with incomplete information. So far, Collin didn't rectify.
But does he _need_ to? It's easy to have imperfect knowledge. We all swim in ignorance.
I advise against personalizing this conflict. And even if you feel insulted, there are hazards to injecting honor-based cultural patterns into technical forums.
I'm deeply familiar with a region of my country that practices such patterns, and I was still very young when I got heartily sick of it.
https://en.wikipedia.org/wiki/Culture_of_honor_(Southern_United_States)
Quoted 8 lines
Quoted 6 lines
Quoted 4 lines
Also relevant is the fact that he accused me of "slowly" documenting "personal preferences". His wording implies that it wasn't there before. Maybe I misunderstood, though. I'd be happy to rectify if I was wrong.
I think he meant in general?
I don't interpret that. I guess he can defend himself and clarify.
Again, does Collin _need_ to? Would it meaningfully advance your objectives if he did?
Some things can be permitted to drop. You can always pick them up again later if someone tries to press your benign neglect to their advantage.
Quoted 10 lines
I only see my style slightly different than Michael's, but not necessarily in the sense of involving a more opinionated approach. See the other messages where I've shown how Michael had done the exact same thing with strlcpy(3) a long time ago.
On reconsideration, and after researching what Michael really did, I think I was wrong saying we have a different style at all. I believe we've had the same style. We just had different topics of expertise.
Michael has had his own share of opinionated comments in manual pages.
You might be completely right about all of this. Maybe people have beatified Michael in the rosy glow of hindsight, and overlooked his less temperate statements. (Some day, they might do the same of you. ;-) )
But I don't see how concern with this matter materially advances the objectives of getting good advice to frustrated or curious programmers into the Linux man-pages, and of making the C Standard Library more comprehensible and less painful to use.
A suggestion I've been meaning to make but have struggled to find a good place to inject is the following:
You've spoken multiple times of about 5 years of your work hammering as hard as you could on the various memory buffer/string interfaces of libc, and how much of the benefit of that work went into the shadow-utils project. And I believe you because I've caught fugitive glimpses of that work over most of that period.
So I recommend, hypocritically, that you engage in a practice that I struggle with:
Promote your work.
What I have in mind is an article, say of the length that a guest columnist might write for LWN, working your way though a selection of the most frustrating or fascinating issues you encountered. To a first approximation, every C programmer believes they know how to use these functions, because hey, how hard could they be? Illustrate the hazards. Show how the naïve assumptions fail. Point to how you solved them in shadow-utils (or elsewhere). Then, as your grand conclusion, show how your proposed reforms to the C standard logically follow.
Circulate that piece, either to a few reviewers whose judgment you trust, or on the linux-man list, possibly marked "[off-topic]" or "[meta]". Engage your reviewers and let them improve it, as Paul Eggert did by pointing out the multiple evaluations of one of your macro arguments. (Even if it didn't matter in that case, it's not a great pattern.)
Does this require more work of you before going to WG14? Yes. But at the end of it you'll have an artifact you can point to. It can be your personal FAQ for this subject. You can mine it for future N papers.
You're doing a lot of work arguing with people on these mailing lists, too. So think of it in terms of opportunity cost. With a "Hard Lessons Learned from string.h" paper, you have an artifact you can point to-- one that is almost certainly going to get read by more people than will follow hyperlinks to mailing list disputes.
And like an N document, an article can be revised over time, whereas with mailing list posts, your errors are burned into the ground to embarrass a person for all eternity.
...except for the fact that correct and incorrect claims alike are much more often utterly forgotten.
Regards,
Branden
Re: the Linux man-pages as an educational tool
In reply to Alejandro ColomarQuoted 7 lines · Alejandro Colomar
[...]
Most programmers can live in the safe bubble of <
string.h>: those functions always require a string as input, and always provide a string as output. Plain and simple. It's difficult to write bugs when using those.
I don't think it is simple to write safe (secure?) code using the interfaces currently provided by libc.* Proof by counterexample:
CVE-2026-5358,
<https://sourceware.org/bugzilla/show_bug.cgi?id=34067>. If the libc maintainers can't write secure code using the existing interfaces, then there's little hope for the rest of us.
[*] libc could provide safer interfaces, but it declined to provide them. Confer, the lack of support for Annex K and the safer string functions. (I'm aware of the politics and the past decisions by folks like Ulrich Drepper).
Jeff
on project management (was: the Linux man-pages as an educational tool)
In reply to Alejandro Colomar[looping in groff list because toward the end of this mail I present some philosophy that I have applied to my work on that project]
Hi Alex,
Quoted 10 lines · Alejandro Colomar
Quoted 6 lines
Date: 2026-08-02 16:27:21-0700
From: Collin Funk <[email protected]>
I can't help but wonder of what happens in WG 14 rejects this controversial, as obvious by this thread, change. Will the man-pages changes be reverted? Or will we slowly watch them document personal preferences instead of existing standards?This patch set is quite independent of the standard. It documents a header file that has been provided since forever in glibc and most other POSIX-ish systems,
Just yesterday while watching an ncurses build scroll by on my tablet, I had occasion to notice that Bionic libc provides a "memory.h" header. Curious, I checked it out.
It's a thin wrapper for <string.h>.
I endorse your reformist attitude because every technological success story begins ossifying as soon as its market position can be milked for economic rent. As the old Demotivator poster said of consulting: "If you're not a part of the solution, there's good money to be made in prolonging the problem."[1]
Thus trigraphs. Thus K&R function declarations. Thus "wastebasket taxon" header files.
Quoted 3 lines
so changes to the standard are unlikely to have any effects. I've clarified this extensively. If you want to discourage me from applying the change, you should rather bring up technical reasons.
I don't think Collin's totally off base.
What is the overall mission of the Linux man-pages project as you conceive it?
Take some time to draft one, if you haven't already and I missed it. Here are some points you might consider.
* Is delivery of factual information more or less important than advocacy of correct methods and accepted idioms?
* If the foregoing are equally important, are you _sure_ they need to be? Can you escape dilemmas that frustrate day-to-day stewardship work by favoring one over the other?
* If you maintain that the two are equally important, nevertheless, how do you resolve conflict? Disclose the principles you employ to decide such issues, and write them down where people can find them. That way they can better understand why you reason the way you do, and you bind yourself to those principles, so that you and others are less seduced by the urge to "shift the goalposts" in a dispute.
Quoted 2 lines
This passive-aggressive message is not something that will have the desired effects you could possibly reach with technical arguments.
I'd say less that it was a passive-aggressive message than that it was a deployment of a slippery-slope argument. Fallaciously? I don't know.
But it is also true that people are pushing back on your proposals regarding reënvisioning of libc's memory buffer and string APIs from two fronts. Only one is technical. The other is managerial.
As a maintainer, your role is to serve your community. This is a privilege and a responsibility. Generally, one is accepted in that role because one has demonstrated a high level of expertise and sufficient resources to carry out the tasks the role requires.
Someone earlier in the thread made reference to the personage of past glibc maintainer Ulrich Drepper, whose maintainership of glibc came to an unhappy end. Anyone who'd deny that Drepper was a world-class domain expert or diligently applied himself to his work, I would not take seriously. Apart from glibc maintenance, he wrote some excellent papers on dynamic shared objects and on the nature of the memory abstraction in Unix and Unix-like systems. (Since the latter paper got so deep into the topic of cache memory architecture, I'd venture it applies more broadly still.)
I reiterate: world-class. Any engineer in this space who doesn't read Drepper disserves themselves professionally. His stuff is up there with Goldberg's 1991 paper on floating-point arithmetic, in my opinion. Even if you don't 100% digest what these people have to say, they'll improve your thinking, because you'll become more familiar with the problem domain. (And if you disagree with them and can back up your claims, start writing a paper of your own. That's where the confidence one manifests in the Google interview or break room evaporates.)
So how does a guy like that get himself into trouble as a maintainer?
By persistently failing to attend to the demands/needs of the community they serve.
Listen to your users. Even if they're "wrong".
Here's how I apply the foregoing mode of analysis to my own work.
I've occasionally ruffled feathers by changing defaults in groff.[2] I _think_ that I have kept myself from being deposed by the sans-culottes by going well out of my way to ensure that configuration knobs are available to override those defaults, to document not just their substance but their rationale, and to present examples in a configuration file in /etc/groff so that all people have to do is uncomment something to override my contemptible idiocy. (Eventually, some learn the hard way why I made my choice.)
Frequently, I pitch potentially disruptive changes--stuff that we'd report in the "NEWS" file--as an email to the groff list with "Proposed:" in the Subject line. More often than not, what I suggest involves such an esoteric detail of formatter behavior that I get no feedback at all. Few have mastered such oddities as diversion trap management, to name an example of something that's moving a little bit in groff 1.25 and might, theoretically,[3] break some old AT&T troff documents (but none written targeting GNU troff itself).
But I also have a counterexample.
2 release cycles in a row, in anticipation of groff 1.24 and 1.25, I've pitched a small redesign of GNU troff such that the configured hyphenation language--basically, the set of patterns used for automatic hyphenation of words, which are locale-specific (English, French, German)--is a property of the environment, like all other hyphenation configuration parameters, rather than a global one.
Twice in a row, one person has spoken against the change--it _would_ require changes to some macro packages. That person is Peter Schaffter, author of mom(7), a macro package that shows off GNU troff's capabilities as a typesetting system better than any other.
I haven't yet managed to make a concrete case to him strongly enough to persuade him that the objective is worth the candle.
Now, I'm dead certain that my proposal is the correct course from a software design perspective. It's a Yourdon/Constantine "cohesion" no-brainer.
But, because environments are formatter-level objects, such a change's impact is not limited to internal data design. It affects the language, and I have users. So, I've interpreted Peter's objection as a procedural veto. Rhetorically, he hasn't been so strident. What I infer is that I need to spend time coming up with one or more concrete exhibits to establish the benefit of the change. I have an idea for what would do it: a multi-lingual document, say an mm(7) document where most of the body text is in English but the document uses the package's "bottom block" BS and BE macros to present at the foot of every page some kind of disclaimer in, for instance, French.
Just articulating the idea isn't enough. Given the unusual resistance on this point, and recognizing the general indulgence shown by the community toward my madcap reformist schemes as something I'd be wise not to squander, I've decided what I need to do is build a real document with a real macro package, and illustrate what changes to that package would be necessary to fulfill the promise of the redesign.
I expect the disruption level to be low and the benefit to be high--for its applicable problem domain. The potential impact either way is limited because multilingual documents are simply not common.
Because groff's community is small, I interpret a single dissenting voice as putting consensus out of reach. It helps in this case that the single dissenting voice is a known member of the community. If our mailing list suffered from anonymous drive-by trolls, I'd be in the perilous position of bifurcating participants into a class that gets "taken seriously" and a class that does not. I spoke earlier in this thread of "moral hazard". I feel there is significant moral hazard in making such classifications. For one thing, sometimes anonymous contributors make cogent points, and for another, temptation is ever present to make the class of "people to be taken seriously" coextensive with those who agree with, flatter, or indulge you.
Kings, presidents, executives, generals, and "BDFL"s express mystification and confusion regarding their failures because they mistake sycophancy for objective judgment.
Regards,
Branden
[1] https://www.reddit.com/r/Demotivational/comments/1fdyxe/consulting/
[2] The most famous example is the great hyphen-minus debacle of 2023.
https://lwn.net/Articles/947941/
[3] And I do mean theoretically. I surveyed a large corpus of historical Unix troff documents and could not find _any_ that came close to slipping through the "hole in the grammar" that I identified and closed.
https://savannah.gnu.org/bugs/?68357#comment1
Alejandro Colomar
maintainerRe: the Linux man-pages as an educational tool
In reply to G. Branden RobinsonHi Branden, Sam,
Quoted 41 lines
Date: 2026-08-03 10:34:56-0500
From: "G. Branden Robinson" <[email protected]>Quoted 10 lines · Alejandro Colomar
Quoted 3 lines
From: Sam James <[email protected]>
Alejandro Colomar <[email protected]> writes:[...]
Quoted 6 lines
Quoted 5 lines
[Collin Funk] doesn't need to have read every word of the glibc manual, but this precise text he could have read it, because it was mentioned by Paul in this thread (different subthread) prior (19:28 UTC) to his message, and reviewed by me also prior (20:31 UTC) to his message (23:27 UTC).
Quoted 7 lines
Quoted 3 lines
I often reply as I go rather than reading all other emails around that time. I don't think you should assume he read those emails and deliberately neglected their contents.
Me too. But eventually I respond to those other emails, and rectify when that new information conflicts with something I said with incomplete information. So far, Collin didn't rectify.
But does he _need_ to? It's easy to have imperfect knowledge. We all swim in ignorance.
I advise against personalizing this conflict. And even if you feel insulted, there are hazards to injecting honor-based cultural patterns into technical forums.
I'm deeply familiar with a region of my country that practices such patterns, and I was still very young when I got heartily sick of it.
https://en.wikipedia.org/wiki/Culture_of_honor_(Southern_United_States)
Quoted 7 lines
Quoted 6 lines
Quoted 4 lines
Also relevant is the fact that he accused me of "slowly" documenting "personal preferences". His wording implies that it wasn't there before. Maybe I misunderstood, though. I'd be happy to rectify if I was wrong.
I think he meant in general?
Quoted 7 lines
Quoted 1 line
I don't interpret that. I guess he can defend himself and clarify.
Again, does Collin _need_ to? Would it meaningfully advance your objectives if he did?
Some things can be permitted to drop. You can always pick them up again later if someone tries to press your benign neglect to their advantage.
No, he doesn't need to. I was and still am willing to let him drop it without any resentment, just as I've always done (or so I think, and try to). Love everyone, no matter what.
But Sam should probably have dropped it too; that's what I intended to mean in my response to Sam.
So, please everyone drop it and calm down. I'm willing to.
Quoted 34 lines
Quoted 10 lines
I only see my style slightly different than Michael's, but not necessarily in the sense of involving a more opinionated approach. See the other messages where I've shown how Michael had done the exact same thing with strlcpy(3) a long time ago.
On reconsideration, and after researching what Michael really did, I think I was wrong saying we have a different style at all. I believe we've had the same style. We just had different topics of expertise.
Michael has had his own share of opinionated comments in manual pages.
You might be completely right about all of this. Maybe people have beatified Michael in the rosy glow of hindsight, and overlooked his less temperate statements. (Some day, they might do the same of you. ;-) )
But I don't see how concern with this matter materially advances the objectives of getting good advice to frustrated or curious programmers into the Linux man-pages, and of making the C Standard Library more comprehensible and less painful to use.
A suggestion I've been meaning to make but have struggled to find a good place to inject is the following:
You've spoken multiple times of about 5 years of your work hammering as hard as you could on the various memory buffer/string interfaces of libc, and how much of the benefit of that work went into the shadow-utils project. And I believe you because I've caught fugitive glimpses of that work over most of that period.
So I recommend, hypocritically, that you engage in a practice that I struggle with:
Promote your work.
Quoted 8 lines
What I have in mind is an article, say of the length that a guest columnist might write for LWN, working your way though a selection of the most frustrating or fascinating issues you encountered. To a first approximation, every C programmer believes they know how to use these functions, because hey, how hard could they be? Illustrate the hazards. Show how the naïve assumptions fail. Point to how you solved them in shadow-utils (or elsewhere). Then, as your grand conclusion, show how your proposed reforms to the C standard logically follow.
I've been wanting to do that for a long time. I just need to do more work for that to be perfect, though. One thing I don't like about articles is that they're immutable, and thus aren't a good teaching material; mistakes will happen that will make the resource problematic.
A benefit of manual pages is that they're a living document that improves with time. Once the pages become close to perfect, it could make sense to write an article that could stand the pass of decades.
If I write such an article, I want it to be valid 50 years from now; and not only valid, but the canonical resource for the topic.
Quoted 6 lines
Circulate that piece, either to a few reviewers whose judgment you trust, or on the linux-man list, possibly marked "[off-topic]" or "[meta]". Engage your reviewers and let them improve it, as Paul Eggert did by pointing out the multiple evaluations of one of your macro arguments. (Even if it didn't matter in that case, it's not a great pattern.)
Indeed; I regard Paul as an expert in this topic. We might slightly disagree, but I acknowledge he's mostly right.
Quoted 3 lines
Does this require more work of you before going to WG14? Yes. But at the end of it you'll have an artifact you can point to. It can be your personal FAQ for this subject. You can mine it for future N papers.
I don't think such an article should be the first step. It should probably be the last: once the documentation and the system provide the tools, the article should summarize that, and be a tutorial for it.
I don't see that article happening before 2030 (possibly much later).
Quoted 9 lines
You're doing a lot of work arguing with people on these mailing lists, too. So think of it in terms of opportunity cost. With a "Hard Lessons Learned from
string.h" paper, you have an artifact you can point to-- one that is almost certainly going to get read by more people than will follow hyperlinks to mailing list disputes.And like an N document, an article can be revised over time, whereas with mailing list posts, your errors are burned into the ground to embarrass a person for all eternity.
I've made enough errors and have been embarrased for many times, that I don't fear that. :)
Also, I think it's easier to rectify mistakes in mailing list discussions, than to rectify an article that thousands of people have read.
Quoted 2 lines
...except for the fact that correct and incorrect claims alike are much more often utterly forgotten.
Have a lovely day! :-)
Alex
Signature · 1 line
<https://www.alejandro-colomar.es>
Re: the Linux man-pages as an educational tool
In reply to Alejandro ColomarQuoted 13 lines · Alejandro Colomar
Hi Sam,
Quoted 5 lines
Date: 2026-08-03 15:05:36+0100
From: Sam James <[email protected]>Alejandro Colomar <[email protected]> writes:
[...]
Quoted 5 lines
Quoted 4 lines
He doesn't need to have read every word of the glibc manual, but this precise text he could have read it, because it was mentioned by Paul in this thread (different subthread) prior (19:28 UTC) to his message, and reviewed by me also prior (20:31 UTC) to his message (23:27 UTC).
Quoted 7 lines
Quoted 3 lines
I often reply as I go rather than reading all other emails around that time. I don't think you should assume he read those emails and deliberately neglected their contents.
Me too. But eventually I respond to those other emails, and rectify when that new information conflicts with something I said with incomplete information. So far, Collin didn't rectify.
Well, give him a chance.
Quoted 14 lines
Quoted 14 lines
Quoted 14 lines
Date: Sun, 2 Aug 2026 14:28:33 -0500 From: Paul Eggert <[email protected]> Message-ID: <[email protected]> Date: Sun, 2 Aug 2026 22:31:59 +0200 From: Alejandro Colomar <[email protected]> Message-ID: <am-eAGL6OWqP9Yah@devuan> Date: Sun, 02 Aug 2026 16:27:21 -0700 From: Collin Funk <[email protected]> Message-ID: <[email protected]>
Quoted 8 lines
Quoted 6 lines
Quoted 4 lines
Also relevant is the fact that he accused me of "slowly" documenting "personal preferences". His wording implies that it wasn't there before. Maybe I misunderstood, though. I'd be happy to rectify if I was wrong.
I think he meant in general?
I don't interpret that. I guess he can defend himself and clarify.
Right.
Quoted 16 lines
Quoted 10 lines
Quoted 4 lines
While he didn't need to know whether it was there before, it would be good to make some effort to learn whether that was the case, before making such a serious accusation.
I took it to be that you (as you've said yourself) have a different style from Michael and this does involve a more opinionated (you may not call it that) approach. He's commenting on that being unfavourable to him. I didn't think that was contentious, more that you see it as your duty wrt education.
I only see my style slightly different than Michael's, but not necessarily in the sense of involving a more opinionated approach. See the other messages where I've shown how Michael had done the exact same thing with strlcpy(3) a long time ago.
Quoted 5 lines
On reconsideration, and after researching what Michael really did, I think I was wrong saying we have a different style at all. I believe we've had the same style. We just had different topics of expertise.
Michael has had his own share of opinionated comments in manual pages.
Yes, seeing the quotes you posted in another reply, I didn't realise he'd written those!
Quoted 4 lines
Have a lovely day!
Alex
Alejandro Colomar
maintainerRe: the Linux man-pages as an educational tool
In reply to Jeffrey WaltonHi Jeff,
Quoted 12 lines
Date: 2026-08-03 12:07:41-0400
From: Jeffrey Walton <[email protected]>Quoted 7 lines · Alejandro Colomar
[...]
Most programmers can live in the safe bubble of <
string.h>: those functions always require a string as input, and always provide a string as output. Plain and simple. It's difficult to write bugs when using those.
Quoted 6 lines
I don't think it is simple to write safe (secure?) code using the interfaces currently provided by libc.* Proof by counterexample:
CVE-2026-5358,
<https://sourceware.org/bugzilla/show_bug.cgi?id=34067>. If the libc maintainers can't write secure code using the existing interfaces, then there's little hope for the rest of us.
Agreed; I didn't mean that limiting oneself to the currently provided libc string APIs is safe. I meant that limiting oneself to APIs that strictly handle strings (including some APIs that are not currently provided by glibc, such as streq(3) and strscpy(9)) is safe (compared to using the non-string APIs.
Quoted 4 lines
[*] libc could provide safer interfaces, but it declined to provide them. Confer, the lack of support for Annex K and the safer string functions. (I'm aware of the politics and the past decisions by folks like Ulrich Drepper).
I don't think Annex K is safe at all. But certainly, some additions would be beneficial.
Have a lovely day!
Alex
Quoted 2 lines
Jeff
Signature · 1 line
<https://www.alejandro-colomar.es>
Alejandro Colomar
maintainerRe: the Linux man-pages as an educational tool
In reply to Sam JamesHi Sam,
First of all, thanks for toning down.
Quoted 9 lines
Quoted 7 lines
Quoted 3 lines
I often reply as I go rather than reading all other emails around that time. I don't think you should assume he read those emails and deliberately neglected their contents.
Me too. But eventually I respond to those other emails, and rectify when that new information conflicts with something I said with incomplete information. So far, Collin didn't rectify.
Well, give him a chance.
Of course. I don't have any resentment at all of anyone in this thread. I might have written more or less heated responses at some points, mistakes are just mistakes, and don't bind anyone. Love is always welcome! :-)
Moreover, I don't think he needs to rectify. We can just forget about this entirely. Really, there's no problem here. We got too opinionated and that caused a flame war. We're all working towards the same goal; let's not fight each other.
I've already committed these changes (yesterday night), with some changes from what we've discussed. I'll apply some more changes after the historic details that Joseph has clarified a moment ago. I'll also apply some other changes from another set of details someone sent (IIRC, from Branden) today.
The manual pages are not written in stone, and I'll continue to revise this documentation. Everyone is welcome to send patches to improve the exact wording.
Please trust me on this specific change and let a year or two pass before asking me to revert it. But I'm open to fully reverting if it becomes evident that I've been wrong.
[...]
Quoted 5 lines
Quoted 5 lines
I only see my style slightly different than Michael's, but not necessarily in the sense of involving a more opinionated approach. See the other messages where I've shown how Michael had done the exact same thing with strlcpy(3) a long time ago.
Quoted 8 lines
Quoted 5 lines
On reconsideration, and after researching what Michael really did, I think I was wrong saying we have a different style at all. I believe we've had the same style. We just had different topics of expertise.
Michael has had his own share of opinionated comments in manual pages.
Yes, seeing the quotes you posted in another reply, I didn't realise he'd written those!
:-)
Cheers,
Alex
Signature · 1 line
<https://www.alejandro-colomar.es>
Re: proposed revision to memory.h(3head)
In reply to Alejandro ColomarQuoted 5 lines · Alejandro Colomar
Most C libraries, including the BSDs, glibc, and musl, provide <
memory.h>.Illumos and gnulib don’t provide it, though, and instead use <
string.h>.
I don't understand why you claim that illumos does not provide a memory.h. It clearly does:
https://github.com/illumos/illumos-gate/blob/master/usr/src/head/memory.h
However, it only declares the 5 functions that were historically declared there: memccpy(), memchr(), memcmp(), memcpy(), and memset(). Including memory.h is not going to pull in declarations of functions that have always been defined as being in string.h, such as the strn*() functions.
This matches what was found in SVR4, the first System V release that was fully unified with standard C and claimed compatibility, and which was the basis for many commercial Unix systems. For backward compatibility SVR4 retained memory.h with the 5 original mem*() declarations, and those declarations were duplicated in string.h for standard C conformance. They did not even add memmove() to memory.h; it was only added to string.h where the standards committee added it.
Also in 4.3 BSD, when they added memory.h for System V compatibility in 1986, it only declared the 5 original mem*() functions. It did not include string.h or declare any str*() or strn*() functions.
So I think you will find that a lot of systems that were following System V or 4.3 BSD may have a memory.h, but it is not going to work the way you are suggesting in the man page.
Quoted 6 lines
Quoted 3 lines
New programmers will follow those
instructions and find their code breaks on illumos, when it really shouldn't.I hope Illumos adds <
memory.h>. Also, I don't expect new programmers to be exactly the kind of programmers that use Illumos.
What operating system do you think is most used by new programmers? You are right that it isn't illumos; it is Microsoft Windows. I'm no Windows expert, so perhaps someone else can confirm, but it appears that Microsoft's C runtime also has a memory.h that declares some functions like memcpy(), but not any strn*() functions which have always been defined to be in string.h. If it's not even in ISO C I doubt you will have much luck convincing Microsoft to add the functions that you decided should be in memory.h.
Suppose I was reviewing some code intended to be portable, that included memory.h for a function that ISO C and POSIX say is declared in string.h and that isn't even one of the 5 original mem*() functions. Even if memory.h works on the author's system, it is by accident. Using the standard string.h header that almost every implementation for decades has strived to comply with avoids easily preventable build failures when attempting to build the code elsewhere. So I would of course reject the code and point the author at the ISO C or POSIX standard. Perhaps you wouldn't because you are willing to fight the other operating systems that don't provide the nonstandard memory.h that you prefer, but I am not willing to do that and I doubt there are many people willing to take up that fight for you without a large standards body like ISO C or POSIX backing them up. I don't want to tell people that the man pages cannot be trusted for accurate information, so I hope that you will not lead me to do that just to avoid the introduction of non-portable code that will cause problems on conforming implementations.
- Mark
Alejandro Colomar
maintainerRe: proposed revision to memory.h(3head)
Hi Mark,
Quoted 7 lines
Date: 2026-08-03 10:58:35-0700
From: Mark Harris <[email protected]>Quoted 3 lines · Alejandro Colomar
Most C libraries, including the BSDs, glibc, and musl, provide <
memory.h>.
Quoted 6 lines
Quoted 2 lines
Illumos and gnulib don’t provide it, though, and instead use <
string.h>.I don't understand why you claim that illumos does not provide a
memory.h. It clearly does:
https://github.com/illumos/illumos-gate/blob/master/usr/src/head/memory.h
Oh, I was expecting to find it under some .../include/ directory. I didn't expect .../head/, and thus my confusion. Thanks!
I'll amend the documentation to say that it also includes is.
Quoted 5 lines
However, it only declares the 5 functions that were historically declared there:
memccpy(),memchr(),memcmp(),memcpy(), andmemset(). Includingmemory.his not going to pull in declarations of functions that have always been defined as being instring.h, such as the strn*() functions.
Thanks! I'll also document this detail.
Quoted 7 lines
This matches what was found in SVR4, the first System V release that was fully unified with standard C and claimed compatibility, and which was the basis for many commercial Unix systems. For backward compatibility SVR4 retained
memory.hwith the 5 original mem*() declarations, and those declarations were duplicated instring.hfor standard C conformance. They did not even addmemmove()tomemory.h; it was only added tostring.hwhere the standards committee added it.
Huh! :)
Quoted 3 lines
Also in 4.3 BSD, when they added
memory.hfor System V compatibility in 1986, it only declared the 5 original mem*() functions. It did not includestring.hor declare any str*() or strn*() functions.
Luckily, the modern BSDs have it as a synonym of <string.h>, and so is musl and glibc. (I guess bionic too.)
But I'll document this detail. It is important.
Quoted 3 lines
So I think you will find that a lot of systems that were following System V or 4.3 BSD may have a
memory.h, but it is not going to work the way you are suggesting in the man page.
I wouldn't say a lot, but certainly some.
Quoted 7 lines
Quoted 6 lines
Quoted 3 lines
New programmers will follow those
instructions and find their code breaks on illumos, when it really shouldn't.I hope Illumos adds <
memory.h>. Also, I don't expect new programmers to be exactly the kind of programmers that use Illumos.
Quoted 8 lines
What operating system do you think is most used by new programmers? You are right that it isn't illumos; it is Microsoft Windows. I'm no Windows expert, so perhaps someone else can confirm, but it appears that Microsoft's C runtime also has a
memory.hthat declares some functions likememcpy(), but not any strn*() functions which have always been defined to be instring.h. If it's not even in ISO C I doubt you will have much luck convincing Microsoft to add the functions that you decided should be inmemory.h.
I've been in contact with the implementors of the MS libc for quite some time already for the fix of realloc(,0) in which I've been working. I might have a handle there. :)
Quoted 9 lines
Suppose I was reviewing some code intended to be portable, that included
memory.hfor a function that ISO C and POSIX say is declared instring.hand that isn't even one of the 5 original mem*() functions. Even ifmemory.hworks on the author's system, it is by accident. Using the standardstring.hheader that almost every implementation for decades has strived to comply with avoids easily preventable build failures when attempting to build the code elsewhere. So I would of course reject the code and point the author at the ISO C or POSIX standard. Perhaps you wouldn't because you are
Quoted 8 lines
willing to fight the other operating systems that don't provide the nonstandard
memory.hthat you prefer, but I am not willing to do that and I doubt there are many people willing to take up that fight for you without a large standards body like ISO C or POSIX backing them up. I don't want to tell people that the man pages cannot be trusted for accurate information, so I hope that you will not lead me to do that just to avoid the introduction of non-portable code that will cause problems on conforming implementations.
The manual pages document the standard header file, of course:
#include <memory.h> // See STANDARDS STANDARDS C11, POSIX.1‐2008. ISO C and POSIX declare this function in <string.h>; see memory.h(3head).
Thanks for the details!
Have a lovely day!
Alex
Quoted 1 line
- Mark
Signature · 1 line
<https://www.alejandro-colomar.es>
Re: the Linux man-pages as an educational tool
In reply to Alejandro ColomarQuoted 3 lines · Alejandro Colomar
If <
string.h> was described as providing functions that exclusively handle strings, then programmers that only need to handle strings would naturally self-limit to functions from this header file.
A one-line change to the description of <string.h> in the C standard, from "String handling" to "String and memory utilities" or similar, to make clear it's *not* (and never has been) exclusively handling strings, might well make sense. That's all the change that I think makes sense in this area.
Signature · 2 lines
Joseph S. Myers [email protected]
Re: the Linux man-pages as an educational tool
In reply to Alejandro ColomarQuoted 7 lines · Alejandro Colomar
Quoted 2 lines
That's basically how it went with 'gets': The community realized it is a bad function, then the implementors started to withdraw it.
Here's an interesting story about gets(3), which I learnt recently:
The C Committee didn't remove it from ISO C. It was the Austin Group that triggered some unusual process within ISO for overriding the C Committee, and removed it in a secret meeting.
That sounds like a myth. You can easily read the October 2009 minutes (N1475), item 4.27 "On The Removal of gets() (N1420) (Stoughton)". You can also see C99 issue 0332 that resulted in the obsolescence in C99 TC3 that was followed by the removal in C11.
Signature · 2 lines
Joseph S. Myers [email protected]
Re: on project management (was: the Linux man-pages as an educational tool)
In reply to G. Branden RobinsonQuoted 18 lines · G. Branden Robinson
[looping in groff list because toward the end of this mail I present some philosophy that I have applied to my work on that project]
Hi Alex,
Quoted 10 lines · Alejandro Colomar
Quoted 6 lines
Date: 2026-08-02 16:27:21-0700
From: Collin Funk <[email protected]>
I can't help but wonder of what happens in WG 14 rejects this controversial, as obvious by this thread, change. Will the man-pages changes be reverted? Or will we slowly watch them document personal preferences instead of existing standards?This patch set is quite independent of the standard. It documents a header file that has been provided since forever in glibc and most other POSIX-ish systems,
Quoted 5 lines
Just yesterday while watching an ncurses build scroll by on my tablet, I had occasion to notice that Bionic libc provides a "
memory.h" header. Curious, I checked it out.It's a thin wrapper for <
string.h>.
the crazy part is that it was an _empty_ file until i made it just #include <string.h>:
https://android-review.googlesource.com/c/platform/bionic/+/52171
i can't explain that (it was originally checked in as an empty file, so the history is no help).
i _can_ explain why i made it match glibc rather than just deleting it
though: i didn't want to break existing code that was [harmlessly] including an empty file, and i wanted to increase the amount of the code from other libcs that would "just work". (and note that ios/macos have a <memory.h> that's just a #include <string.h> too.)
Quoted 168 lines
I endorse your reformist attitude because every technological success story begins ossifying as soon as its market position can be milked for economic rent. As the old Demotivator poster said of consulting: "If you're not a part of the solution, there's good money to be made in prolonging the problem."[1]
Thus trigraphs. Thus K&R function declarations. Thus "wastebasket taxon" header files.
Quoted 3 lines
so changes to the standard are unlikely to have any effects. I've clarified this extensively. If you want to discourage me from applying the change, you should rather bring up technical reasons.
I don't think Collin's totally off base.
What is the overall mission of the Linux man-pages project as you conceive it?
Take some time to draft one, if you haven't already and I missed it. Here are some points you might consider.
* Is delivery of factual information more or less important than advocacy of correct methods and accepted idioms?
* If the foregoing are equally important, are you _sure_ they need to be? Can you escape dilemmas that frustrate day-to-day stewardship work by favoring one over the other?
* If you maintain that the two are equally important, nevertheless, how do you resolve conflict? Disclose the principles you employ to decide such issues, and write them down where people can find them. That way they can better understand why you reason the way you do, and you bind yourself to those principles, so that you and others are less seduced by the urge to "shift the goalposts" in a dispute.
Quoted 2 lines
This passive-aggressive message is not something that will have the desired effects you could possibly reach with technical arguments.
I'd say less that it was a passive-aggressive message than that it was a deployment of a slippery-slope argument. Fallaciously? I don't know.
But it is also true that people are pushing back on your proposals regarding reënvisioning of libc's memory buffer and string APIs from two fronts. Only one is technical. The other is managerial.
As a maintainer, your role is to serve your community. This is a privilege and a responsibility. Generally, one is accepted in that role because one has demonstrated a high level of expertise and sufficient resources to carry out the tasks the role requires.
Someone earlier in the thread made reference to the personage of past glibc maintainer Ulrich Drepper, whose maintainership of glibc came to an unhappy end. Anyone who'd deny that Drepper was a world-class domain expert or diligently applied himself to his work, I would not take seriously. Apart from glibc maintenance, he wrote some excellent papers on dynamic shared objects and on the nature of the memory abstraction in Unix and Unix-like systems. (Since the latter paper got so deep into the topic of cache memory architecture, I'd venture it applies more broadly still.)
I reiterate: world-class. Any engineer in this space who doesn't read Drepper disserves themselves professionally. His stuff is up there with Goldberg's 1991 paper on floating-point arithmetic, in my opinion. Even if you don't 100% digest what these people have to say, they'll improve your thinking, because you'll become more familiar with the problem domain. (And if you disagree with them and can back up your claims, start writing a paper of your own. That's where the confidence one manifests in the Google interview or break room evaporates.)
So how does a guy like that get himself into trouble as a maintainer?
By persistently failing to attend to the demands/needs of the community they serve.
Listen to your users. Even if they're "wrong".
Here's how I apply the foregoing mode of analysis to my own work.
I've occasionally ruffled feathers by changing defaults in groff.[2] I _think_ that I have kept myself from being deposed by the sans-culottes by going well out of my way to ensure that configuration knobs are available to override those defaults, to document not just their substance but their rationale, and to present examples in a configuration file in
/etc/groffso that all people have to do is uncomment something to override my contemptible idiocy. (Eventually, some learn the hard way why I made my choice.)Frequently, I pitch potentially disruptive changes--stuff that we'd report in the "NEWS" file--as an email to the groff list with "Proposed:" in the Subject line. More often than not, what I suggest involves such an esoteric detail of formatter behavior that I get no feedback at all. Few have mastered such oddities as diversion trap management, to name an example of something that's moving a little bit in groff 1.25 and might, theoretically,[3] break some old AT&T troff documents (but none written targeting GNU troff itself).
But I also have a counterexample.
2 release cycles in a row, in anticipation of groff 1.24 and 1.25, I've pitched a small redesign of GNU troff such that the configured hyphenation language--basically, the set of patterns used for automatic hyphenation of words, which are locale-specific (English, French, German)--is a property of the environment, like all other hyphenation configuration parameters, rather than a global one.
Twice in a row, one person has spoken against the change--it _would_ require changes to some macro packages. That person is Peter Schaffter, author of mom(7), a macro package that shows off GNU troff's capabilities as a typesetting system better than any other.
I haven't yet managed to make a concrete case to him strongly enough to persuade him that the objective is worth the candle.
Now, I'm dead certain that my proposal is the correct course from a software design perspective. It's a Yourdon/Constantine "cohesion" no-brainer.
But, because environments are formatter-level objects, such a change's impact is not limited to internal data design. It affects the language, and I have users. So, I've interpreted Peter's objection as a procedural veto. Rhetorically, he hasn't been so strident. What I infer is that I need to spend time coming up with one or more concrete exhibits to establish the benefit of the change. I have an idea for what would do it: a multi-lingual document, say an mm(7) document where most of the body text is in English but the document uses the package's "bottom block"
BSandBEmacros to present at the foot of every page some kind of disclaimer in, for instance, French.Just articulating the idea isn't enough. Given the unusual resistance on this point, and recognizing the general indulgence shown by the community toward my madcap reformist schemes as something I'd be wise not to squander, I've decided what I need to do is build a real document with a real macro package, and illustrate what changes to that package would be necessary to fulfill the promise of the redesign.
I expect the disruption level to be low and the benefit to be high--for its applicable problem domain. The potential impact either way is limited because multilingual documents are simply not common.
Because groff's community is small, I interpret a single dissenting voice as putting consensus out of reach. It helps in this case that the single dissenting voice is a known member of the community. If our mailing list suffered from anonymous drive-by trolls, I'd be in the perilous position of bifurcating participants into a class that gets "taken seriously" and a class that does not. I spoke earlier in this thread of "moral hazard". I feel there is significant moral hazard in making such classifications. For one thing, sometimes anonymous contributors make cogent points, and for another, temptation is ever present to make the class of "people to be taken seriously" coextensive with those who agree with, flatter, or indulge you.
Kings, presidents, executives, generals, and "BDFL"s express mystification and confusion regarding their failures because they mistake sycophancy for objective judgment.
Regards,
Branden[1] https://www.reddit.com/r/Demotivational/comments/1fdyxe/consulting/
[2] The most famous example is the great hyphen-minus debacle of 2023.
https://lwn.net/Articles/947941/[3] And I do mean theoretically. I surveyed a large corpus of historical Unix troff documents and could not find _any_ that came close to slipping through the "hole in the grammar" that I identified and closed.
https://savannah.gnu.org/bugs/?68357#comment1
Alejandro Colomar
maintainerRe: the Linux man-pages as an educational tool
In reply to Joseph MyersHi Joseph,
Quoted 9 lines
Date: 2026-08-03 19:31:19+0000
From: Joseph Myers <[email protected]>Quoted 3 lines · Alejandro Colomar
If <
string.h> was described as providing functions that exclusively handle strings, then programmers that only need to handle strings would naturally self-limit to functions from this header file.
Quoted 5 lines
A one-line change to the description of <
string.h> in the C standard, from "String handling" to "String and memory utilities" or similar, to make clear it's *not* (and never has been) exclusively handling strings, might well make sense. That's all the change that I think makes sense in this area.
Please propose it. I'd likely vote for it; it can be a positive change.
It certainly wouldn't be a one-line change, given that you'd also have to change things like '7.28.1 String function conventions', and quite a few others, but yeah, I get and support your idea.
I believe adding <memory.h> can be even better than that, but at least your proposal is in the good direction.
As I said in my last message to Sam, if the currnt man-pages change proves to be problematic contrary to my expectations, I will revisit this and revert the documentation change.
We can also improve the wording in the meantime if the current man-pages text is sub-optimal.
Have a lovely day!
Alex
Signature · 1 line
<https://www.alejandro-colomar.es>
Alejandro Colomar
maintainerRe: the Linux man-pages as an educational tool
In reply to Joseph MyersHi Joseph,
Quoted 13 lines
Date: 2026-08-03 19:45:06+0000
From: Joseph Myers <[email protected]>Quoted 7 lines · Alejandro Colomar
Quoted 2 lines
That's basically how it went with 'gets': The community realized it is a bad function, then the implementors started to withdraw it.
Here's an interesting story about gets(3), which I learnt recently:
The C Committee didn't remove it from ISO C. It was the Austin Group that triggered some unusual process within ISO for overriding the C Committee, and removed it in a secret meeting.
Quoted 4 lines
That sounds like a myth. You can easily read the October 2009 minutes (N1475), item 4.27 "On The Removal of
gets()(N1420) (Stoughton)". You can also see C99 issue 0332 that resulted in the obsolescence in C99 TC3 that was followed by the removal in C11.
It could very well be a myth. For the outsiders, it was the WG14 convenor who told us this story some days ago.
Cheers,
Alex
Signature · 1 line
<https://www.alejandro-colomar.es>
Re: proposed revision to memory.h(3head)
In reply to Alejandro ColomarQuoted 2 lines · Alejandro Colomar
SYNOPSIS
#include <memory.h> // See STANDARDSintro(3) implies that the SYNOPSIS section intends to reflect the function's API; i.e., the interface that it has agreed to provide to applications. Do you disagree?
If strndup(3)'s SYNOPSIS stated "int" instead of "size_t" for the second argument, it may work fine in many cases but that is not the API that it has agreed to provide so it is inaccurate. Similarly if it states "memory.h" instead of "string.h", even if it happens to work on some systems, that is not the API it has agreed to provide so it is inaccurate. If memory.h ceases to provide a usable declaration for strndup(), that is the problem of the person that relied on the inaccurate information because there was never any agreement to provide a usable declaration of strndup() in memory.h; they should have used a reliable source to determine the API that is actually supported. I am having trouble figuring out where you disagree with this seemingly-straightforward logic.
- Mark
Re: on project management
In reply to enhQuoted 4 lines · enh
the crazy part is that it was an _empty_ file until i made it just #include <
string.h>:
https://android-review.googlesource.com/c/platform/bionic/+/52171
Quoted 8 lines
i can't explain that (it was originally checked in as an empty file, so the history is no help).
i _can_ explain why i made it match glibc rather than just deleting it
though: i didn't want to break existing code that was [harmlessly] including an empty file, and i wanted to increase the amount of the code from other libcs that would "just work". (and note that ios/macos have a <memory.h> that's just a #include <string.h> too.)
I think this partially confirms my suspicion earlier, that the only reason anyone ever included <memory.h> is because on some system stuff they wanted was not in <string.h> (but was only in the latter on some). So the former tends to be included only when the latter is also, to cover both cases.
I'd confirm definitely by getting the list of files from Debian codesearch that include one and the other and comparing it, but I wasn't able to figure out how to do that.
Signature · 1 line
Arsen Arsenović
Alejandro Colomar
maintainerRe: proposed revision to memory.h(3head)
In reply to Mark HarrisHi Mark,
Quoted 11 lines
Date: 2026-08-03 13:14:35-0700
From: Mark Harris <[email protected]>Quoted 2 lines · Alejandro Colomar
SYNOPSIS #include <memory.h> // See STANDARDSintro(3) implies that the SYNOPSIS section intends to reflect the function's API; i.e., the interface that it has agreed to provide to applications. Do you disagree?
Quoted 12 lines
If strndup(3)'s SYNOPSIS stated "int" instead of "
size_t" for the second argument, it may work fine in many cases but that is not the API that it has agreed to provide so it is inaccurate. Similarly if it states "memory.h" instead of "string.h", even if it happens to work on some systems, that is not the API it has agreed to provide so it is inaccurate. Ifmemory.hceases to provide a usable declaration forstrndup(), that is the problem of the person that relied on the inaccurate information because there was never any agreement to provide a usable declaration ofstrndup()inmemory.h; they should have used a reliable source to determine the API that is actually supported. I am having trouble figuring out where you disagree with this seemingly-straightforward logic.
There are already pages where we can't even consider a unified interface. Let's consider the case of ttyslot(3), once part of SUSv1, then obsoleted in SUSv2, and then removed in POSIX.1-2001, but still provided by the usual systems.
The SYNOPSIS says:
SYNOPSIS #include <unistd.h> /* See NOTES */ int ttyslot(void); Feature Test Macro Requirements for glibc (see feature_test_macros(7)): ...
But then, of course, the actual #include is a real mess.
Funnily, there's no NOTES section, because I moved their contents to more specific sections some years ago (we were never happy about the NOTES section being so generic, and so I eventually put some order there, but of course, some parts weren't perfectly moved).
Okay, let's ignore the fact that there's no NOTES, and assume the comment meant to say 'See HISTORY'. Here's what HISTORY has to say about the #include's for this function:
The glibc2 implementation of this function reads the file _PATH_TTYS, defined in <ttyent.h> as "/etc/ttys". It re‐ turns 0 on error. Since Linux systems do not usually have "/etc/ttys", it will always return 0.
On BSD‐like systems and Linux, the declaration of ttys‐ lot() is provided by <unistd.h>. On System V‐like sys‐
tems, the declaration is provided by <stdlib.h>. Since
glibc 2.24, <stdlib.h> also provides the declaration with the following feature test macro definitions:
(_XOPEN_SOURCE >= 500 ||
(_XOPEN_SOURCE && _XOPEN_SOURCE_EXTENDED))
&& ! (_POSIX_C_SOURCE >= 200112L || _XOPEN_SOURCE >= 600)
SYNOPSIS is kind of a TL;DR. In some cases, what it says is all there is. In other cases, there's a lot of details. When there are details, tradition is that the SYNOPSIS at least hints that the user should continue reading somewhere.
In the more than thousand pages we have, you can find counter-examples for almost everything you could expect from a manual page.
Have a lovely night!
Alex
Signature · 1 line
<https://www.alejandro-colomar.es>
Re: the Linux man-pages as an educational tool
In reply to Sam JamesQuoted 20 lines · Sam James
Quoted 18 lines · Alejandro Colomar
Hi Collin,
Quoted 3 lines
Date: 2026-08-02 16:27:21-0700
From: Collin Funk <[email protected]>[...]
Quoted 5 lines
I can't help but wonder of what happens in WG 14 rejects this controversial, as obvious by this thread, change. Will the man-pages changes be reverted? Or will we slowly watch them document personal preferences instead of existing standards?
This patch set is quite independent of the standard. It documents a header file that has been provided since forever in glibc and most other POSIX-ish systems, so changes to the standard are unlikely to have any effects. I've clarified this extensively. If you want to discourage me from applying the change, you should rather bring up technical reasons.
Quoted 7 lines
Quoted 2 lines
This passive-aggressive message is not something that will have the desired effects you could possibly reach with technical arguments.
I didn't read it as passive-aggressive, but I will say that I think you've gone a bit hard in the responses to Collin in this subthread, and I think the fact you sent several followup emails to yourself indicates perhaps things got heated in the moment.
The last sentence was probably a bit rude, sorry about that. However, I think a reasonable third party can understand my frustration. Almost everyone who has responded in this thread has been against the change, and have spent time writing their rationale. They simply receive a response that can be summarized as "strncpy and friends are confusing", or pointed to a much less commonly used man page which does not align with standards for historic reasons, or told they are not rationalizing enough.
I no longer consider this thread a productive use of time, so I won't respond to further messages. I am happy enough to fix the SYNOPSIS of my man pages locally like this:
$ git grep -lF '<memory.h>' \
| xargs -n 1 sed -i 's|<memory.h>.*|<string.h>|g'Hopefully distributions consider doing the same.
Collin
Re: [PATCH 1/2] man/man3/{mem, strn}*(): SYNOPSIS, STANDARDS: Document these as provided by <memory.h>
In reply to Alejandro ColomarQuoted 8 lines · Alejandro Colomar
From: Collin Funk <[email protected]>
Quoted 7 lines
Quoted 1 line · Joseph Myers
I'd rather we add a mandatory deprecation warning to
memory.hin glibc.I would be for this change, and am surprised it has not already been done, to honest. The use of
memory.his a good indicator code hasn't been touched since the 80s.
I agree. <memory.h> is a legacy header, and it has only redirected to <string.h> for ages, for even-older-code compatibility. Many environments do not have it at all, and let’s leave it at that.
It’s so obscure I haven’t needed to use it on *any* of the platforms mksh got ported to, and those are extensive.
Quoted 1 line
Or that it has been touched in 2026. :)
Please don’t try to unilaterally introduce even more splintering of portable C programming. This will hurt and make standards into competing instead of compatible again.
Thanks.
(Please do not add me to the Cc list, I don’t have enough tuits for this.)
bye,
//mirabilos
Signature · 4 lines
FWIW, I'm quite impressed with mksh interactively. I thought it was much *much* more bare bones. But it turns out it beats the living hell out of ksh93 in that respect. I'd even consider it for my daily use if I hadn't wasted half my life on my zsh setup. :-) -- Frank Terbeck in #!/bin/mksh
Re: proposed revision to memory.h(3head)
In reply to Alejandro ColomarQuoted 64 lines · Alejandro Colomar
Hi Mark,
Quoted 11 lines
Date: 2026-08-03 13:14:35-0700
From: Mark Harris <[email protected]>Quoted 2 lines · Alejandro Colomar
SYNOPSIS #include <memory.h> // See STANDARDSintro(3) implies that the SYNOPSIS section intends to reflect the function's API; i.e., the interface that it has agreed to provide to applications. Do you disagree?
Quoted 12 lines
If strndup(3)'s SYNOPSIS stated "int" instead of "
size_t" for the second argument, it may work fine in many cases but that is not the API that it has agreed to provide so it is inaccurate. Similarly if it states "memory.h" instead of "string.h", even if it happens to work on some systems, that is not the API it has agreed to provide so it is inaccurate. Ifmemory.hceases to provide a usable declaration forstrndup(), that is the problem of the person that relied on the inaccurate information because there was never any agreement to provide a usable declaration ofstrndup()inmemory.h; they should have used a reliable source to determine the API that is actually supported. I am having trouble figuring out where you disagree with this seemingly-straightforward logic.There are already pages where we can't even consider a unified interface. Let's consider the case of ttyslot(3), once part of SUSv1, then obsoleted in SUSv2, and then removed in POSIX.1-2001, but still provided by the usual systems.
The SYNOPSIS says:
SYNOPSIS #include <unistd.h> /* See NOTES */ int ttyslot(void); Feature Test Macro Requirements for glibc (see feature_test_macros(7)): ...But then, of course, the actual #include is a real mess.
Funnily, there's no NOTES section, because I moved their contents to more specific sections some years ago (we were never happy about the NOTES section being so generic, and so I eventually put some order there, but of course, some parts weren't perfectly moved).
Okay, let's ignore the fact that there's no NOTES, and assume the comment meant to say 'See HISTORY'. Here's what HISTORY has to say about the #include's for this function:
The glibc2 implementation of this function reads the file
_PATH_TTYS, defined in <ttyent.h> as "/etc/ttys". It re‐ turns 0 on error. Since Linux systems do not usually have "/etc/ttys", it will always return 0.On BSD‐like systems and Linux, the declaration of ttys‐
lot()is provided by <unistd.h>. On System V‐like sys‐
tems, the declaration is provided by <stdlib.h>. Since
glibc 2.24, <stdlib.h> also provides the declaration with the following feature test macro definitions:
Quoted 8 lines
(
_XOPEN_SOURCE>= 500 ||
(_XOPEN_SOURCE&&_XOPEN_SOURCE_EXTENDED))
&& ! (_POSIX_C_SOURCE>= 200112L ||_XOPEN_SOURCE>= 600)SYNOPSIS is kind of a TL;DR. In some cases, what it says is all there is. In other cases, there's a lot of details. When there are details, tradition is that the SYNOPSIS at least hints that the user should continue reading somewhere.
I wasn't asking about your comment "// See STANDARDS". I understand that you had more to share that was too long for the SYNOPSIS section, so you added the comment. I was asking about why you wrote an inaccurate include directive in the SYNOPSIS section that does not reflect the supported API of any implementation. Even after reading the STANDARDS section, the implication is that the supported API is memory.h, but POSIX says it should be string.h. However, even if you had your own libc implementation, it would be inaccurate to claim that the supported API is memory.h for any more than your own libc; you obviously cannot unilaterally change the supported API for implementations supported by other groups.
- Mark
Alejandro Colomar
maintainerRe: the Linux man-pages as an educational tool
In reply to Collin FunkHi Collin,
Quoted 28 lines
Date: 2026-08-03 19:39:43-0700
From: Collin Funk <[email protected]>Quoted 23 lines · Sam James
Quoted 20 lines · Alejandro Colomar
Hi Collin,
Quoted 3 lines
Date: 2026-08-02 16:27:21-0700
From: Collin Funk <[email protected]>[...]
Quoted 5 lines
I can't help but wonder of what happens in WG 14 rejects this controversial, as obvious by this thread, change. Will the man-pages changes be reverted? Or will we slowly watch them document personal preferences instead of existing standards?
This patch set is quite independent of the standard. It documents a header file that has been provided since forever in glibc and most other POSIX-ish systems, so changes to the standard are unlikely to have any effects. I've clarified this extensively. If you want to discourage me from applying the change, you should rather bring up technical reasons.
This passive-aggressive message is not something that will have the desired effects you could possibly reach with technical arguments.
Quoted 6 lines
Quoted 4 lines
I didn't read it as passive-aggressive, but I will say that I think you've gone a bit hard in the responses to Collin in this subthread, and I think the fact you sent several followup emails to yourself indicates perhaps things got heated in the moment.
The last sentence was probably a bit rude, sorry about that.
No problem; thanks!
Quoted 2 lines
However, I
think a reasonable third party can understand my frustration.
I hope you can understand mine too.
[...]
Quoted 7 lines
I am happy enough to fix the SYNOPSIS of my
man pages locally like this:$ git grep -lF '<memory.h>' \ | xargs -n 1 sed -i 's|<memory.h>.*|<string.h>|g'Hopefully distributions consider doing the same.
I've thought a bit more about it, and had an idea that might be a reasonable compromise.
Here's a sample:
SYNOPSIS - #include <memory.h> // See STANDARDS + #include <string.h> // or <memory.h>; see memory.h(3head) void *memccpy(size_t n; void dest[restrict n], const void src[restrict n], @@ -34,8 +34,6 @@ ATTRIBUTES STANDARDS POSIX.1‐2008. - ISO C and POSIX declare this function in <string.h>; see memory.h(3head). -
Here's the commit message, which explains why I believe this is a reasonable compromise:
man/man3/: Put first <string.h> in SYNOPSIS, then comment about <memory.h>
This is a compromise between the fact that <string.h> is the standard header and (only slightly) most portable header file for these functions, while hinting at the fact that it might be more appropriate to use <memory.h> where possible.
Remove the STANDARDS and NOTES about this, since now the SYNOPSIS contains all the necessary information. The extra info is in memory.h(3head), which is linked to in the SYNOPSIS.
What do you think?
Have a lovely day!
Alex
Signature · 1 line
<https://www.alejandro-colomar.es>
Re: the Linux man-pages as an educational tool
Quoted 28 lines · Alejandro Colomar
I've thought a bit more about it, and had an idea that might be a reasonable compromise.
Here's a sample:
SYNOPSIS - #include <memory.h> // See STANDARDS + #include <string.h> // or <memory.h>; see memory.h(3head) void *memccpy(size_t n; void dest[restrict n], const void src[restrict n], @@ -34,8 +34,6 @@ ATTRIBUTES STANDARDS POSIX.1‐2008. - ISO C and POSIX declare this function in <string.h>; see memory.h(3head). -Here's the commit message, which explains why I believe this is a reasonable compromise:
man/man3/: Put first <
string.h> in SYNOPSIS, then comment about <memory.h>This is a compromise between the fact that <
string.h> is the standard header and (only slightly) most portable header file for these functions, while hinting at the fact that it might be more appropriate to use <memory.h> where possible.
Quoted 5 lines
Remove the STANDARDS and NOTES about this, since now the SYNOPSIS contains all the necessary information. The extra info is in
memory.h(3head), which is linked to in the SYNOPSIS.What do you think?
Why, though?
I think that, in the thread, it was already demonstrated (by Bionic having an empty memory.h for a time) that nobody includes <memory.h> on its own and expects to see these functions. (not that Bionic is that widely-used; a better test would be checking something like Debian codesearch)
As I've noted before, what header provides what declaration is also largely inconsequential.
So, the only effect of this can be to create new cases where <memory.h> is included, for no gain.
It doesn't really matter that memory.h is only slightly less portable, IMO. It is unused, to the point where Autoconf recommends not using it, and no longer bothers checking whether 'mem*' functions are also present in string.h.
Is suddenly reviving a dead header to copy a few declarations of functions well known to be part of string.h into it not just unneeded churn? Especially as program code would (nearly?) always need to do:
#include <string.h>
#ifdef HAVE_MEMORY_H
# include <memory.h> #endif
Signature · 1 line
Arsen Arsenović
Alejandro Colomar
maintainerThe goal of the Linux man-pages project
Hi Arsen,
Quoted 3 lines
Date: 2026-08-04 17:49:43+0200
From: Arsen Arsenović <[email protected]>
[...]
Quoted 7 lines
Quoted 7 lines
man/man3/: Put first <
string.h> in SYNOPSIS, then comment about <memory.h>This is a compromise between the fact that <
string.h> is the standard header and (only slightly) most portable header file for these functions, while hinting at the fact that it might be more appropriate to use <memory.h> where possible.
Quoted 7 lines
Quoted 5 lines
Remove the STANDARDS and NOTES about this, since now the SYNOPSIS contains all the necessary information. The extra info is in
memory.h(3head), which is linked to in the SYNOPSIS.What do you think?
Why, though?
To help guide programmers to understand these APIs, and consequentially be able to write better code. That's the goal of this project. It's the Linux Programmer's Manual, and its purpose is that programmers on a Linux system are able to write correct programs.
The purpose of this documentation is not, and was never supposed to be, a technical specification of the implementation.
Branden asked me yesterday:
| Date: 2026-08-03 11:09:02-0500 | From: "G. Branden Robinson" <[email protected]> | Message-ID: <20260803160902.5edjmpxaqr5uudbu@illithid> | | What is the overall mission of the Linux man-pages project as you | conceive it?
Here's my reply.
A programmer should be able to write correct code.
A piece of documentation that describes an API in detail --as if it were reverse-engineering it from its binary code-- but doesn't tell me how to use it correctly is useless.
Let's take an example. Here's the description of strncpy(3) as of man-pages-5.05 (right before my first patch to the project):
The strcpy() function copies the string pointed to by src, including the terminating null byte ('\0'), to the buffer pointed to by dest. The strings may not overlap, and the destination string dest must be large enough to receive the copy. Beware of buffer overruns! (See BUGS.)
The strncpy() function is similar, except that at most n bytes of src are copied. Warning: If there is no null byte among the first n bytes of src, the string placed in dest will not be null‐terminated.
If the length of src is less than n, strncpy() writes ad‐ ditional null bytes to dest to ensure that a total of n bytes are written.
Okay, we have an algorithm. I'm sure you can implement strncpy(3) from that description. But what is it useful for? Why would I want to call it? How do I even call it?
The page even continues with an actual implementation.
A simple implementation of strncpy() might be:
char *
strncpy(char *dest, const char *src, size_t n)
{
size_t i;
for (i = 0; i < n && src[i] != '\0'; i++)
dest[i] = src[i];
for ( ; i < n; i++)
dest[i] = '\0';
return dest;
}Well, if someone misunderstood the reverse-engineered description, now they should have it clear. Still, as a user, I don't give a shit about any of the text I've read. What is this good for? How do I use it? Should I use it at all? This is the 'Linux Programmer’s Manual', as the page says at the top, but as a programmer, I don't know what to do with this. How am I supposed to write programs in a Linux system?
Branden continued with more questions:
| Take some time to draft one, if you haven't already and I missed it. | Here are some points you might consider. | | * Is delivery of factual information more or less important than | advocacy of correct methods and accepted idioms?
I continue with my reply:
Factual information is useless if it can't be interpreted. The only thing that matters is that the programmer is able to, well, program. Of course, the program should be correct, and as safe/simple as possible/reasonable.
'Accepted' idioms is something that doesn't strike me as an unconditionally good thing. Back in the times of Galileo, it was accepted that the Earth didn't move. Good documentation might need to exceptionally reject accepted idioms, even if most of the time they'll be good.
So, maybe correct methods would be the priority, with accepted idioms and factual information being secondary to it.
Quoted 3 lines
I think that, in the thread, it was already demonstrated (by Bionic having an empty
memory.hfor a time) that nobody includes <memory.h> on its own and expects to see these functions.
This is part of 'factual information', which is only a secondary goal of this documentation project, as stated above.
The purpose of this change is to help form a mental model of how these memory and string functions relate to each other, and how they behave.
Quoted 6 lines
(not that Bionic is that
widely-used; a better test would be checking something like Debian codesearch)As I've noted before, what header provides what declaration is also largely inconsequential.
If it is largely inconsequential, I expect this change shouldn't be as controversial as it seemed to be.
Quoted 2 lines
So, the only effect of this can be to create new cases where <
memory.h> is included, for no gain.
I don't agree with the 'for no gain' claim. But yes, the first part of the sentence is certainly true.
Quoted 4 lines
It doesn't really matter that
memory.his only slightly less portable, IMO. It is unused, to the point where Autoconf recommends not using it, and no longer bothers checking whether 'mem*' functions are also present instring.h.
It doesn't really matter that it is unused. What matters is that it can be used just fine, and will help --IMO-- understand these functions better.
Quoted 8 lines
Is suddenly reviving a dead header to copy a few declarations of functions well known to be part of
string.hinto it not just unneeded churn? Especially as program code would (nearly?) always need to do:#include <string.h> #ifdef HAVE_MEMORY_H # include <memory.h> #endif
Are there any systems without <memory.h>? We've been seeing in this thread that most systems have it. Even Microsoft has it. I bet most programs can live without that conditional.
I'd say most programs would be portable enough with this:
#include <string.h> #include <memory.h>
Have a lovely day!
Alex
Signature · 1 line
<https://www.alejandro-colomar.es>
Re: The goal of the Linux man-pages project
What follows is my opinion. You are free to have a different opinion, but please don't tell me my opinion is wrong ;-)
Quoted 2 lines · Alejandro Colomar
It's the Linux Programmer's Manual, and its purpose is that programmers on a Linux system are able to write correct programs.
I think I disagree with the scope of "write correct programs" here. "Write programs that use the APIs in a way that won't break" is not the same as "write programs that use best practices", but "correct" covers both.
Quoted 2 lines
The purpose of this documentation is not, and was never supposed to be, a technical specification of the implementation.
In the past, that's exactly what man pages were. You'd get a box of printed manuals, one or more per section, with one or more pages per program/file/function being described, and that was the gold standard reference for the system the books came with. Heck, even "man man" says it's for the "system reference manuals".
I think that, in so far as the the developer wants to use our APIs, the man pages must document what "is" and the information the developer needs to use the APIs. Note that I don't say "correctly" because that's too vague - we should cover the correct way to *call* a function, but not the correct way to *use* a function - if the programmer wants to abuse the function for their own purpose, so be it.
If the man pages say what a function does, and what its parameters are, and what it returns, that is unbiased factual documentation which the programmer can use as they wish.
Where the man pages go beyond this, we call that "examples", "caveats", and "best practices" and we have to be careful to disclose that they're just recommendations. It is not our place to tell the developer how to write *their* code, beyond interfacing to our APIs.
I think the man pages need to, where appropriate, document the STANDARD way of doing things, not what the author thinks might be better, or what has been historically popular. In the case of string.h vs memory.h, we should take guidance from the current relevant published standards, because future standards will assume that also. If current standards conflict with older standards, we could document that (perhaps in a CAVEATS or HISTORY section). We should NOT try to anticipate future standards in the man pages, or suggest "best practices" that rely on future standards.
Quoted 1 line
A programmer should be able to write correct code.
We need to leave the definition of "correct" up to the programmer, outside of "legal API use". Their code needs to do what they want, not what we want, so long as the programmer sticks to the standards for our APIs.
Quoted 3 lines
A piece of documentation that describes an API in detail --as if it were reverse-engineering it from its binary code-- but doesn't tell me how to use it correctly is useless.
Again with "correct". We need to document how to use it "according to what the standards allow and what the function needs and does", and possibly provide examples and caveats, but avoid trying to say "and you should use it for these purposes."
Quoted 3 lines
Okay, we have an algorithm. I'm sure you can implement strncpy(3) from that description. But what is it useful for? Why would I want to call it?
Who cares? We're not the developers, let them use the function if the algorithm fits their needs. We document printf() but don't tell the developer what data they should print, just *how* to print it. Same here. Tell the developer what the function does, but leave *why* to use it up to them.
If you want to add a HISTORY section that explains the original purpose of the function, go ahead. But that has nothing to do with current "correct" usage.
Quoted 1 line
How do I even call it?
That's the API that we need to document. HOW is relevent here, WHY is not.
Quoted 1 line
How am I supposed to write programs in a Linux system?
I think what you want is a programmer's guide. While that may be something to include in The Linux Documentation Project, it's outside the scope of the man pages. Even the TLDP FAQ says it provide "Guides, HOWTOs, man pages, and FAQs", which implies that man pages are neither guides nor HOWTOs.
Do I think we need more documentation to help people write better software? Yes! Do I think the man pages are the right place for that? No.
Quoted 1 line
Are there any systems without <
memory.h>?
Irrelevant. If the standard says those functions are in <string.h>, that's what we should document in the pages for those functions.
Re: [GNULIB] The goal of the Linux man-pages project
In reply to Alejandro ColomarHi all,
I think I might be repeating myself a bit, but i would like to express a subjective conclusion but from a point of an objective observer, so i had to repeat some bits.
But first, lets start that i'm feeling that we owe to Alejandro, and [t]his email I'm ansering should be the proof.
Look. People around here i breath, are without second thought the kings of selfishness.
They really like their a.h and they do their best to put it in comfort. But:
When they are involved on cases that there is no gain for them, they are and without second thought the kings of justness. This brings the desired balance. There is a poem, that became a song, and could easily be our national anthem that says: "Sun of justice, whom we feel"
Now, let's go dive in deep, and keep it short :).
Is there anyone out there, that if we started afresh a libc and the standard, who believes that mem*() belong to string.h header?
Look, there is this one special thing that can characterize a programmer, and this is preciseness! Based on that, i really believe that every sane C programmer in this planet, would be voting for a header like memory.h, because that is the of their operation. End of story.
Again and to Alex mostly:
Judging from the current glorious! circumstances we live, to ask from old dogd to make such trycks is unreasonable. This is not a fight that deserves to spend our valuable energy. End of story. I believe you'll understand. Again, you are tottally precise. And in my opinion, you can be accused for overheated enthusiasm or overzealously, but with no way for irresponsibility (quite the contrary!), and in my opinion you are deserving an apology.
But and to be precise, we all owe to Branden (I can't remember the last time I met such a crystal logic, and it feels like a gift (thankfully this giant (mostly useless) thread offered some value :))).
To others: please offer some trust to Alex. He proved (okey he is selfish like every f atom in this world we know) that is capable to change mind and offer a way out. But is ridicoulous to ask by him to bow in his knees and loose his mind. Because it is clear that he believes that he is doing the right thing. So again give him some space and trust. We all (always) need each other, but especially those brilliant moments we live. Please don't give the machine the chance to do even a bit more than it should do. It is obviously fatal if we give it even a bit of space out of what we can control with confidence.
Many thanks for listening.
Re: [GNULIB] The goal of the Linux man-pages project
Sorry and be precise:
Quoted 4 lines · On Tue, Aug 04, at 11:14 Αγαθοκλής Χατζημανίκας wrote:
Look, there is this one special thing that can characterize a programmer, and this is preciseness! Based on that, i really believe that every sane C programmer in this planet, would be voting for a header like
memory.h, because that is the
kind
Quoted 4 lines
of their operation. End of story.
Judging from the current glorious! circumstances we live, to ask from old dogd
dogs
Quoted 1 line
to make such trycks is unreasonable.
And I said old just because i'm almost sure there will be no new. We are the last of at least __this__ kind.
Hopefully this email is the end of this kind of discussion, though he made us to realize a couple of really important things. So at the end might give us a fresh start. What a situation!
Alejandro Colomar
maintainerRe: The goal of the Linux man-pages project
In reply to DJ DelorieHi DJ,
Quoted 5 lines
Date: 2026-08-04 16:04:24-0400
From: DJ Delorie <[email protected]>What follows is my opinion. You are free to have a different opinion, but please don't tell me my opinion is wrong ;-)
Of course. I'll only tell you where I agree, and where I (and others) disagree. But you're right to defend it. :-)
Quoted 9 lines
Quoted 2 lines · Alejandro Colomar
It's the Linux Programmer's Manual, and its purpose is that programmers on a Linux system are able to write correct programs.
I think I disagree with the scope of "write correct programs" here. "Write programs that use the APIs in a way that won't break" is not the same as "write programs that use best practices", but "correct" covers both.
Quoted 4 lines
Quoted 2 lines
The purpose of this documentation is not, and was never supposed to be, a technical specification of the implementation.
In the past, that's exactly what man pages were.
The 'past' is too broad. Let's clarify that a bit before continuing.
In the times of V7 Unix, yes, that's (probably) exactly what man pages were. I want to produce a modern PDF of the old manuals, which would help me read those and come to my own conclusion, but from what I've heard, that seems to be what they were.
At some point, that started to change.
The Linux manual pages, as of its first release (1.0, in 1993), the page gets(3) --by Thomas Koenig-- said this about the function:
Because it is impossible to tell without knowing the data in advance how many characters gets() will read, and be‐ cause gets() will continue to store characters past the end of the buffer, it is extremely dangerous to use. It has been used to break computer security. Use fgets() in‐ stead.
I suspect that if things like this weren't common earlier, it's because such problems often had not yet been discovered, and so 'best practices' wasn't yet a thing.
You could argue that since there's no way to use this API without breaking the program, this is within scope.
man-pages-1.2 (also 1993), says this about sprintf(3):
Because sprintf and vsprintf assume an arbitrarily long string, callers must be careful not to overflow the actual space; this is often impossible to assure. Note that the length of the strings produced is locale‐dependent and difficult to predict. Use snprintf and vsnprintf instead (or asprintf and vasprintf).
That text seems to have been derived from the 4.4BSD page. The text was added to the 4.4BSD page in 1991 by Keith Bostic
<https://github.com/dspinellis/unix-history-repo/commit/f2e7cd24c8ac>:
Because sprintf() and vsprintf() assume an infinitely long string, callers must be careful not to overflow the actual space; this is often impossible to assure. For safety, programmers should use the snprintf() interface instead. Unfortunately, this interface is not portable.
This is more in the territory of best practices. Programs can perfectly use sprintf(3) if they fully control the input and use a specific locale. This is, in fact, the reason why sprintf(3) still exists: there are legitimate users. It's at the limit of being another gets(3), but it isn't.
In man-pages-3.42 (2012), in strcpy(3), Michael Kerrisk wrote some text recommending the use of strlcpy/cat(3) instead of str[n]cpy(3). This is already deep into the territory of best practices.
In 2014, Theo de Raadt made the wording that discouraged str[n]cpy(3) in OpenBSD harsher than it was:
Author: deraadt <[email protected]>
Date: 2014-04-19 11:30:40 +0000
Use somewhat harsher language and better examples; demonstrate that non-dangerous use functions is difficult.
ok guenther
This includes text in DESCRIPTION:
+Bounds checking must be performed manually with great care. +If the buffer
+.Fa dst
+is not large enough to hold the result, +subsequent memory will be damaged.
Of course, he went much harsher in the EXAMPLES.
Before that, in 1993, Todd C. Miller, had already started discouraging strncpy(3), and recommended strlcpy(3) instead (by then, only in EXAMPLES).
After researching into the history of these string functions, I'd say best practices got their way into manual pages as early as they were developed. The more important they were, the more they made their way into the more important sections of a manual page.
Of course, most of that still was reserved for EXAMPLES/CAVEATS/BUGS, and still is.
Quoted 5 lines
You'd get a box of
printed manuals, one or more per section, with one or more pages per program/file/function being described, and that was the gold standard reference for the system the books came with. Heck, even "man man" says it's for the "system reference manuals".
That was a time when programmers were not so much (at all?) worried about safety, to be fair.
Quoted 2 lines
I think that, in so far as the the developer wants to use our APIs, the man pages must document what "is"
Sure; technical specification is _part_ of the contents of a manual page. I only mean that they must not be limited to that.
Quoted 5 lines
and the information the developer needs to use the APIs. Note that I don't say "correctly" because that's
too vague - we should cover the correct way to *call* a function, but not the correct way to *use* a function - if the programmer wants to abuse the function for their own purpose, so be it.
Here's where we disagree. I believe we must document the way to _use_ a function (and from what I've researched, so did many others before me). We must certainly also document how to call it, of course.
Of course, if the programmer wants to go their own way, and abuse the function, they're free to do so. That information doesn't hurt (except for the people that feel offended by the fact that documentation tells them that what they do is not a best practice).
Quoted 7 lines
If the man pages say what a function does, and what its parameters are, and what it returns, that is unbiased factual documentation which the programmer can use as they wish.
Where the man pages go beyond this, we call that "examples", "caveats", and "best practices" and we have to be careful to disclose that they're just recommendations.
Most of it, yes, certainly. A few glimpses of it may come in the DESCRIPTION, when it's important enough to point early to those other sections where that information is expanded.
Quoted 2 lines
It is not our place to tell the developer how to write *their* code, beyond interfacing to our APIs.
It is our job to explain how they can write their code. Once they know what they can and should do, they're free to break the rules.
Quoted 2 lines
I think the man pages need to, where appropriate, document the STANDARD way of doing things,
The standards don't document ways of doing things, but rather give technical specifications.
Quoted 2 lines
not what the author thinks might be better,
or what has been historically popular.
This conflicts with the contents of manual pages since the BSDs in (at least) 1991.
I believe both belong in manual pages.
Quoted 3 lines
In the case of
string.hvsmemory.h, we
should take guidance from the current relevant published standards, because future standards will assume that also.
Future standards are yet to be written. We don't know what they'll assume.
Quoted 5 lines
If current standards
conflict with older standards, we could document that (perhaps in a CAVEATS or HISTORY section). We should NOT try to anticipate future standards in the man pages, or suggest "best practices" that rely on future standards.
I have not documented any future standards in this case. You might have been confused. I have documented something that is current reality in existing systems (and extension to the standards), and which I pretend to propose for standardization --but that's orthogonal--.
I have indeed documented future standards in very few cases (for example, in countof(3)), but that feature is already part of GCC, and thus it had to be documented. The reference to C2y there is mostly as a warning to readers (essentially meaning: if you don't use C2y, you may want to not use this yet).
Maybe you misunderstood something in this discussion, I guess.
Quoted 7 lines
Quoted 1 line
A programmer should be able to write correct code.
We need to leave the definition of "correct" up to the programmer, outside of "legal API use". Their code needs to do what they want, not what we want, so long as the programmer sticks to the standards for our APIs.
Quoted 8 lines
Quoted 3 lines
A piece of documentation that describes an API in detail --as if it were reverse-engineering it from its binary code-- but doesn't tell me how to use it correctly is useless.
Again with "correct". We need to document how to use it "according to what the standards allow and what the function needs and does", and possibly provide examples and caveats, but avoid trying to say "and you should use it for these purposes."
I wonder if you think the glibc is wrong with these recommendations.
<https://sourceware.org/glibc/manual/latest/html_mono/libc.html#index-strcat>
As noted below, this function has significant performance issues.
...
Whenever a programmer feels the need to use strcat she or he should think twice and look through the program to see whether the code cannot be rewritten to take advantage of already calculated results.
<https://sourceware.org/glibc/manual/latest/html_mono/libc.html#index-strncpy>
This function was designed for now-rarely-used arrays consisting of non-null bytes followed by zero or more null bytes. It needs to set all size bytes of the destination, even when size is much greater than the length of from. As noted below, this function is generally a poor choice for processing strings.
Because these functions can abruptly truncate strings or wide strings, they are generally poor choices for processing them. [...]
Although some buffer overruns can be prevented by manually replacing calls to copying functions with calls to truncation functions, there are often easier and safer automatic techniques, such as fortification (see Fortification of function calls) and AddressSanitizer (see Program Instrumentation Options in Using GCC). Because truncation functions can mask application bugs that would otherwise be caught by the automatic techniques, these functions should be used only when the application’s underlying logic requires truncation.
FWIW, I think it wrong about the performance issue of the cat functions, but it does well informing users about how these functions should and should not be used.
Note that none of this text is in bugs/caveats/notes/etc. FWIW, there's a 'Note' right below that text. Somehow, the other text is more important than a note.
Maybe some people believe a texinfo manual has a right to go into these details, while a manual page must be purely technical. I believe manual pages should document as much as a texinfo manual.
Quoted 6 lines
Quoted 3 lines
Okay, we have an algorithm. I'm sure you can implement strncpy(3) from that description. But what is it useful for? Why would I want to call it?
Who cares? We're not the developers, let them use the function if the algorithm fits their needs.
How will they know? You're assuming programmers that read the algorithm and magically know that they want to use this function.
Quoted 5 lines
We document
printf()but don't tell the
developer what data they should print, just *how* to print it. Same here. Tell the developer what the function does, but leave *why* to use it up to them.
Quoted 8 lines
If you want to add a HISTORY section that explains the original purpose of the function, go ahead. But that has nothing to do with current "correct" usage.
Quoted 1 line
How do I even call it?
That's the API that we need to document. HOW is relevent here, WHY is not.
What do I pass to it? I know it's a 'const char*'; but what should it contain? The page says bytes (maybe a string? it said something about being similar to strcpy(3), but then said it's different), but that's not very useful.
Quoted 7 lines
Quoted 1 line
How am I supposed to write programs in a Linux system?
I think what you want is a programmer's guide. While that may be something to include in The Linux Documentation Project, it's outside the scope of the man pages. Even the TLDP FAQ says it provide "Guides, HOWTOs, man pages, and FAQs", which implies that man pages are neither guides nor HOWTOs.
Yeah, I'm aware some users of the manual pages think they should not guide. I'm happy that many other maintainers before me didn't agree with that (at least, per what we can observe from their actions). Of course, I don't want them to be book-long pages, and in most cases, they don't need anything at all. But in some functions, there needs to be a guide.
Quoted 3 lines
Do I think we need more documentation to help people write better software? Yes! Do I think the man pages are the right place for that? No.
Okay; so you probably think the glibc manual is correct containing that guiding material.
There are many people --like me-- who only ever consult manual pages, and those also need to be guided. Maybe just a few words, but it helps.
Quoted 4 lines
Quoted 1 line
Are there any systems without <
memory.h>?Irrelevant. If the standard says those functions are in <
string.h>, that's what we should document in the pages for those functions.
And we document that.
SYNOPSIS #include <string.h> // or <memory.h>; see memory.h(3head) void *memcpy(size_t n; void dest[restrict n], const void src[restrict n], size_t n);
Let's say that comment is the "guiding material". It's not too intrusive, but it's there for anyone who wants to follow it.
Have a lovely night!
Alex
Signature · 1 line
<https://www.alejandro-colomar.es>
Re: The goal of the Linux man-pages project
In reply to Alejandro ColomarHi Alex,
Quoted 11 lines · Alejandro Colomar
Quoted 11 lines
Quoted 11 lines
man/man3/: Put first <
string.h> in SYNOPSIS, then comment about <memory.h>This is a compromise between the fact that <
string.h> is the standard header and (only slightly) most portable header file for these functions, while hinting at the fact that it might be more appropriate to use <memory.h> where possible.Remove the STANDARDS and NOTES about this, since now the SYNOPSIS contains all the necessary information. The extra info is in
memory.h(3head), which is linked to in the SYNOPSIS.
Quoted 8 lines
Quoted 3 lines
Quoted 1 line
What do you think?
Why, though?
To help guide programmers to understand these APIs, and consequentially be able to write better code. That's the goal of this project. It's the Linux Programmer's Manual, and its purpose is that programmers on a Linux system are able to write correct programs.
First of, this doesn't answer the question I asked. Why should this change, even the "compromise", be done?
But, ignoring that this doesn't answer the question posed, how exactly is hinting that it's "more appropriate to use <memory.h> where possible" accomplishing the goals of the project you've stated there?
It seems to me to just sow confusion.
I think the references to <memory.h> should be confined to a single page that documents what it is, memory.h(3head) or whatever, which should be honest and say only:
<memory.h> is an obsolete header. It exists for compatibility with older programs, and is implemented as an alias of <string.h>.
This makes it clear that the header is never useful, and that it's strictly redundant with <string.h>, in a way that still lets someone reading old code discover it.
The latter, of course, being much more widely used, and standardized. The former being used only to placate pre-standard programs.
It seems to me that your intent was also to standardize memory.h. In this I also see no benefit. string.h can't be split at this point, nor can the real memory.h installed by libcs be shrunk by removing str* from it.
I'll skip the rest of the philosophizing about the purpose of the man-pages project, but I will add that if the Linux man-pages project starts diverging from harmless standard practice to promote idiosyncrasies, I'll have no choice but to caution against relying on it.
Quoted 9 lines
Quoted 3 lines
I think that, in the thread, it was already demonstrated (by Bionic having an empty
memory.hfor a time) that nobody includes <memory.h> on its own and expects to see these functions.This is part of 'factual information', which is only a secondary goal of this documentation project, as stated above.
The purpose of this change is to help form a mental model of how these memory and string functions relate to each other, and how they behave.
The mental model is certainly not helped by prominently featuring a long-dead headers which may (or may not! as seen above) contain declarations from <string.h> (which is a header you consequently have to include anyway).
Quoted 9 lines
Quoted 6 lines
(not that Bionic is that
widely-used; a better test would be checking something like Debian codesearch)As I've noted before, what header provides what declaration is also largely inconsequential.
If it is largely inconsequential, I expect this change shouldn't be as controversial as it seemed to be.
It is largely inconsequential how a declaration is obtained from the perspective of a programmer for reasons I've stated before.
The act of *documenting* a long dead non-standard header as a header that provides some function has a consequence, that consequence being that now a long-dead non-standard header gets included far more frequently.
This means that its only effect is a detriment.
I think it's a far better idea to start emitting a warning when it is included, to indicate that it's an obsolete non-standard header.
Quoted 5 lines
Quoted 2 lines
So, the only effect of this can be to create new cases where <
memory.h> is included, for no gain.I don't agree with the 'for no gain' claim. But yes, the first part of the sentence is certainly true.
There is no gain, the programmer can't tell where a declaration comes from, and this include is strictly redundant with string.h even on all the various Linux systems.
Quoted 7 lines
Quoted 4 lines
It doesn't really matter that
memory.his only slightly less portable, IMO. It is unused, to the point where Autoconf recommends not using it, and no longer bothers checking whether 'mem*' functions are also present instring.h.It doesn't really matter that it is unused. What matters is that it can be used just fine, [...]
Can it? I don't accept that premise. It's a non-standard header.
Quoted 1 line
[...] and will help --IMO-- understand these functions better.
I don't accept that either: I see no way in which understanding benefits from this change.
Quoted 9 lines
Quoted 8 lines
Is suddenly reviving a dead header to copy a few declarations of functions well known to be part of
string.hinto it not just unneeded churn? Especially as program code would (nearly?) always need to do:#include <string.h> #ifdef HAVE_MEMORY_H # include <memory.h> #endif
Quoted 8 lines
Are there any systems without <
memory.h>? We've been seeing in this thread that most systems have it. Even Microsoft has it. I bet most programs can live without that conditional.I'd say most programs would be portable enough with this:
#include <string.h> #include <memory.h>
And even more of them can live with:
#include <string.h>
That said, I imagine that many systems do have it. After all, it is quite cheap to run the following during an install step:
echo '#include <string.h>' > $(DESTDIR)$(includedir)/memory.h
... but, I also would not fault a system for not having it.
We could check what systems have it and whether any do anything besides including string.h.
Or we could just avoid prominently featuring a long-dead non-standard header.
Signature · 1 line
Arsen Arsenović
Alejandro Colomar
maintainerRe: The goal of the Linux man-pages project
Hi Arsen,
Quoted 40 lines
Date: 2026-08-05 11:31:11+0200
From: Arsen Arsenović <[email protected]>Hi Alex,
Quoted 11 lines · Alejandro Colomar
Quoted 11 lines
Quoted 11 lines
man/man3/: Put first <
string.h> in SYNOPSIS, then comment about <memory.h>This is a compromise between the fact that <
string.h> is the standard header and (only slightly) most portable header file for these functions, while hinting at the fact that it might be more appropriate to use <memory.h> where possible.Remove the STANDARDS and NOTES about this, since now the SYNOPSIS contains all the necessary information. The extra info is in
memory.h(3head), which is linked to in the SYNOPSIS.Quoted 8 lines
Quoted 3 lines
Quoted 1 line
What do you think?
Why, though?
To help guide programmers to understand these APIs, and consequentially be able to write better code. That's the goal of this project. It's the Linux Programmer's Manual, and its purpose is that programmers on a Linux system are able to write correct programs.
First of, this doesn't answer the question I asked. Why should this change, even the "compromise", be done?
But, ignoring that this doesn't answer the question posed, how exactly is hinting that it's "more appropriate to use <
memory.h> where possible" accomplishing the goals of the project you've stated there?It seems to me to just sow confusion.
I think the references to <
memory.h> should be confined to a single page that documents what it is,memory.h(3head)or whatever, which should be honest and say only:
Quoted 6 lines
<
memory.h> is an obsolete header. It exists for compatibility with older programs, and is implemented as an alias of <string.h>.This makes it clear that the header is never useful, and that it's strictly redundant with <
string.h>, in a way that still lets someone reading old code discover it.
You've convinced me to further reduce the change. I've removed any explicit suggestions in the functions' pages about including <memory.h>. They're not necessary for the purpose they were meant for. Here's how memcpy(3) looks like now:
SYNOPSIS #include <string.h> // see memory.h(3head) void *memcpy(size_t n; void dest[restrict n], const void src[restrict n], size_t n);
The only reference is a comment to read the memory.h(3head) manual page, as it contains historic details that are relevant about this header file. The fact that <string.h> is the only header file included, and there no "or ...", clearly says that programmers should include <string.h>.
We (or at least I) still want to clarify --already at the point where <string.h> is used-- that <string.h> is the right header for this function as a result of a historical mistake --which we can't solve at this point in time, but it still is an (ossified) mistake--.
This should accomplish the fundamental objective of this change, which is to clarify users that these functions are not strictly string APIs (even if they might be used for strings, in some cases, and with great
care). The pure string APIs don't have this comment, as they naturally
belong in <string.h>.
The <memory.h> manual page is now the only place that documents an '#include <memory.h>', for obvious reasons, and tells a detailed history of why things happened as they happened.
memory.h(3head) memory.h(3head)
NAME
memory.h - memory operations
LIBRARY
Standard C library (libc, -lc)
SYNOPSIS
#include <memory.h>
DESCRIPTION
Write
bzero(3)
memset(3)
Copy
memmove(3)
memcpy(3)
mempcpy(3)
memccpy(3)
strncpy(3)
Catenate
strncat(3)
Duplicate
strndup(3)
strndupa(3)
Compare
memcmp(3)
strncmp(3)
strncasecmp(3)
Search
memchr(3)
memrchr(3)
memmem(3)
VERSIONS
In some systems (Illumos), <memory.h> contains only a few of these functions, and thus <string.h> is needed.
STANDARDS
BSD.
These functions are also provided in <string.h>, as speci‐ fied by ISO C. This is a historic mistake maintained for
compatibility reasons. Don’t let that fool you; these
functions don’t necessarily operate on strings.
HISTORY
SVr1, 4.3BSD.
System V (1983) introduced an initial set of mem* func‐ tions in a <memory.h> header file. 4.3BSD (1986) adopted them.
SVID Issue 1 (1985) standardized this header file, but stated that the functions would be moved to <string.h>.
XPG Issue 3 (1989) listed <memory.h> as WITHDRAWN, and stated that the functions had been moved to <string.h>.
C89 didn’t standardize this header file and instead speci‐ fied all these functions in <string.h>.
This merge of header files has historically confused pro‐ grammers about the real purpose of these functions.
Most C libraries, including the BSDs, glibc, musl, Bionic, and Illumos continue to provide <memory.h>.
gnulib doesn’t provide it, though, and instead uses <string.h>.
SEE ALSO
string(3), string_copying(7)
Linux man‐pages 6.18‐18... 2026‐08‐04 memory.h(3head)
I believe this text is quite objective. It doesn't anywhere suggest that users keep using it, as glibc maintainers have strongly pushed for. It doesn't subjectively discourage its use either, though. It just gives a detailed clarification of how portable it is (which might indeed discourage its use).
I believe the way this is documented will result in readers being more aware of this history, which would help for example programmers find existing uses of <memory.h> and wondering if they can remove them.
Does this sound reasonable to you?
I might be persuaded of further tweaks to this, FWIW.
Have a lovely day!
Alex
Signature · 1 line
<https://www.alejandro-colomar.es>
Re: The goal of the Linux man-pages project
Quoted 2 lines · Alejandro Colomar
SYNOPSIS #include <string.h> // see memory.h(3head)
This belongs in either SEE ALSO or FILES.
Quoted 5 lines
STANDARDS
BSD.These functions are also provided in <
string.h>, as speci‐ fied by ISO C.
Ok so far
Quoted 3 lines
This is a historic mistake maintained for
compatibility reasons. Don’t let that fool you; these
functions don’t necessarily operate on strings.
This just doesn't fit, it's far too opinionated and personal. It needs to be more neutral and standards-respecting.
"Historically, this file contained memory-related functions, while string.h contained string-related functions, but currently these functions are all in string.h, despite these not being string functions, and typically memory.h just includes string.h for compatibility across all the historic standards."
I'm not arguing against the message here, just the tone.
As for the message...
I think the only way we could be more persuasive is if we convinced the standards committees to actually segregate string and memory functions in the specifications, and tell you to ("shall") include string.h or memory.h accordingly, but that would break a lot of programs if it was actually required ("must").
As an interim step, we could get the standards to specify string.h for string functions and memory.h for memory functions ("should"), knowing that either include gives you both, and at a later date (after all the software is migrated) change to "shall" and start encouraging providers to actually segregate them. Or offer a #define that strictly separates them to aid in migration, such as we do with other api-breaking standards changes.
Alejandro Colomar
maintainerRe: The goal of the Linux man-pages project
Hi DJ,
Thanks a lot for this feedback! I appreciate the constructive tone! :)
Quoted 8 lines
Date: 2026-08-05 10:50:30-0400
From: DJ Delorie <[email protected]>Quoted 2 lines · Alejandro Colomar
SYNOPSIS #include <string.h> // see memory.h(3head)This belongs in either SEE ALSO or FILES.
It's _also_ in SEE ALSO.
$ MANWIDTH=64 man memcpy | grep -C1 memory.h SYNOPSIS #include <string.h> // see memory.h(3head)
-- SEE ALSO memory.h(3head), bcopy(3), memccpy(3), memmove(3), mem‐ pcpy(3), strcpy(3), strncpy(3), wmemcpy(3)
FILES is rarely used in man3; when used, it's more about configuration files, and not includes. SYNOPSIS is the main place where we currently specify files.
Actually, this reminds me again of the documentation of types, which are often provided in several header files. I used NOTES in those, because I couldn't think of a good section for that. See for example the NOTES section of size_t(3type):
NOTES size_t The following headers also provide size_t: <aio.h>, <glob.h>, <grp.h>, <iconv.h>, <monetary.h>, <mqueue.h>, <ndbm.h>, <pwd.h>, <regex.h>, <search.h>, <signal.h>, <stdio.h>, <stdlib.h>, <string.h>, <strings.h>, <sys/mman.h>, <sys/msg.h>, <sys/sem.h>, <sys/shm.h>, <sys/socket.h>, <sys/types.h>, <sys/uio.h>, <time.h>, <unistd.h>, <wchar.h>, and <wordexp.h>. ssize_t The following headers also provide ssize_t: <aio.h>, <monetary.h>, <mqueue.h>, <stdio.h>, <sys/msg.h>, <sys/socket.h>, <sys/uio.h>, and <unistd.h>.
I think it could make sense to move that to a FILES section.
About being in SYNOPSIS, I think I want it there, because it's not there as documenting a header file that provides this function, but mainly as documenting that while it's provided by <string.h> it's not a string function.
Quoted 15 lines
Quoted 5 lines
STANDARDS
BSD.These functions are also provided in <
string.h>, as speci‐ fied by ISO C.Ok so far
Quoted 3 lines
This is a historic mistake maintained for
compatibility reasons. Don’t let that fool you; these
functions don’t necessarily operate on strings.This just doesn't fit, it's far too opinionated and personal. It needs to be more neutral and standards-respecting.
Quoted 7 lines
"Historically, this file contained memory-related functions, while
string.hcontained string-related functions, but currently these functions are all instring.h, despite these not being string functions, and typicallymemory.hjust includesstring.hfor compatibility across all the historic standards."I'm not arguing against the message here, just the tone.
I believe your suggestion removes the idea that the message intended to give, but I concede that the tone was too harsh.
Author: Alejandro Colomar <[email protected]> Date: 2026-08-05 17:11:04 +0200 man/man3head/memory.h.3head: STANDARDS: Neutralize the tone Reported-by: DJ Delorie <[email protected]> Signed-off-by: Alejandro Colomar <[email protected]> diff --git a/man/man3head/memory.h.3head b/man/man3head/memory.h.3head index 6c04722c4cf3..59f91e2ed023 100644 --- a/man/man3head/memory.h.3head +++ b/man/man3head/memory.h.3head @@ -65,8 +65,7 @@ .SH STANDARDS These functions are also provided in .IR <string.h> , as specified by ISO C. -This is a historic mistake maintained for compatibility reasons. -Don't let that fool you; +This is a historic mistake maintained for compatibility reasons; these functions don't necessarily operate on strings. .SH HISTORY SVr1, 4.3BSD.
Removing the "don't let that fool you" should neutralize the tone. I prefer keeping the "historic mistake maintained for compatibility reasons", because it really was a mistake, and I believe it is good to acknowledge mistakes. Documenting a mistake doesn't mean we're disrespecting the authors; just that with the information we have today, we wish it was different.
Quoted 7 lines
As for the message...
I think the only way we could be more persuasive is if we convinced the standards committees to actually segregate string and memory functions in the specifications, and tell you to ("shall") include
string.hormemory.haccordingly, but that would break a lot of programs if it was actually required ("must").
Agreed.
Quoted 3 lines
As an interim step, we could get the standards to specify
string.hfor string functions andmemory.hfor memory functions ("should"), knowing that either include gives you both,
That is more or less what my draft of the standards proposal says.
My proposal doesn't provide the str[^n]*() functions in <memory.h>, though. I think it's much better if that remains a vendor extension.
Quoted 5 lines
and at a later date (after all the
software is migrated) change to "shall" and start encouraging providers to actually segregate them. Or offer a #define that strictly separates them to aid in migration, such as we do with other api-breaking standards changes.
Have a lovely day!
Alex
Signature · 1 line
<https://www.alejandro-colomar.es>
Re: on project management
In reply to Arsen ArsenovićHello,
Arsen Arsenovic wrote on Mon, Aug 03, 2026 at 11:09:40PM +0200:
Quoted 15 lines
Quoted 4 lines · enh
the crazy part is that it was an _empty_ file until i made it just #include <
string.h>:
https://android-review.googlesource.com/c/platform/bionic/+/52171Quoted 8 lines
i can't explain that (it was originally checked in as an empty file, so the history is no help).
i _can_ explain why i made it match glibc rather than just deleting it
though: i didn't want to break existing code that was [harmlessly] including an empty file, and i wanted to increase the amount of the code from other libcs that would "just work". (and note that ios/macos have a <memory.h> that's just a #include <string.h> too.)
Quoted 5 lines
I think this partially confirms my suspicion earlier, that the only reason anyone ever included <
memory.h> is because on some system stuff they wanted was not in <string.h> (but was only in the latter on some). So the former tends to be included only when the latter is also, to cover both cases.
I think i can improve this understanding by providing some historical facts. While <memory.h> almost certainly did not originate in BSD, BSD history can still provide some hints how it came to be.
The earliest instance of <memory.h> i'm able to find in my private archives of free historical source code archives is this file include/memory.h from 4.3 BSD:
/*
* Copyright (c) 1985 Regents of the University of California.
* All rights reserved. The Berkeley software License Agreement
* specifies the terms and conditions for redistribution. *
* @(#)memory.h 5.1 (Berkeley) 85/08/05
*/
/*
* Definitions of the Sys5 compat memory manipulation routines */
extern char *memccpy(); extern char *memchr(); extern int memcmp(); extern char *memcpy(); extern char *memset();
[I must admit the Copyright & license header feels bogus to me.
According to the SCCS logs, the person who originally checked in this file into version control was Robert Elz <kre@>. It seems highly unlikely that Robert - or any other UCB employee or associate - wrote these function prototypes. On top of that, function prototypes are not usually considered Copyrightable, and even if they were in principle, there is barely any copyrightable text here.
Then again, none of this matters much, if you put a Copyright notice on an empty or almost empty file that contains nothing Copyrightable, the notice simply means nothing.]
This comment appears to claim that <memory.h> along with these five functions came from AT&T System V UNIX, almost half a decade before ANSI C 89 standardized them to live in <string.h>.
While, as others observed, many systems still contain <memory.h> as a thin compatibility wrapper around <string.h>, having it doesn't seem particularly important at this point. Who wants to really maintain compatibility with System V based systems that are about 35 to 40 years old and significantly predate ANSI C?
That said, i believe the reason most systems did not outright delete <memory.h> is that i fail to see an easy argument what benefit exactly that might provide, apart from general cleanliness.
Quoted 3 lines
I'd confirm definitely by getting the list of files from Debian codesearch that include one and the other and comparing it, but I wasn't able to figure out how to do that.
I fear you may be looking at entirely the wrong era. The Debian project can be considered way too newfangled to provide any substantial insight here. :-D
Yours,
Ingo
Re: on project management
[cc'ing kre@ for the first hand information]
Quoted 47 lines · Ingo Schwarze
Arsen Arsenovic wrote on Mon, Aug 03, 2026 at 11:09:40PM +0200:
Quoted 15 lines
Quoted 4 lines · enh
the crazy part is that it was an _empty_ file until i made it just #include <
string.h>:
https://android-review.googlesource.com/c/platform/bionic/+/52171Quoted 8 lines
i can't explain that (it was originally checked in as an empty file, so the history is no help).
i _can_ explain why i made it match glibc rather than just deleting it
though: i didn't want to break existing code that was [harmlessly] including an empty file, and i wanted to increase the amount of the code from other libcs that would "just work". (and note that ios/macos have a <memory.h> that's just a #include <string.h> too.)Quoted 5 lines
I think this partially confirms my suspicion earlier, that the only reason anyone ever included <
memory.h> is because on some system stuff they wanted was not in <string.h> (but was only in the latter on some). So the former tends to be included only when the latter is also, to cover both cases.I think i can improve this understanding by providing some historical facts. While <
memory.h> almost certainly did not originate in BSD, BSD history can still provide some hints how it came to be.The earliest instance of <
memory.h> i'm able to find in my private archives of free historical source code archives is this fileinclude/memory.hfrom 4.3 BSD:/*
* Copyright (c) 1985 Regents of the University of California.
* All rights reserved. The Berkeley software License Agreement
* specifies the terms and conditions for redistribution. *
* @(#)memory.h 5.1 (Berkeley) 85/08/05
*//*
* Definitions of the Sys5 compat memory manipulation routines */extern char *memccpy(); extern char *memchr(); extern int memcmp(); extern char *memcpy(); extern char *memset();
...
Quoted 10 lines
This comment appears to claim that <
memory.h> along with these five functions came from AT&T System V UNIX, almost half a decade before ANSI C 89 standardized them to live in <string.h>.While, as others observed, many systems still contain <
memory.h> as a thin compatibility wrapper around <string.h>, having it doesn't seem particularly important at this point. Who wants to really maintain compatibility with System V based systems that are about 35 to 40 years old and significantly predate ANSI C?
Quoted 3 lines
That said, i believe the reason most systems did not outright delete <
memory.h> is that i fail to see an easy argument what benefit exactly that might provide, apart from general cleanliness.
ISTR (from the very early 90s) that memory.h was indeed the SysV thing. This was before autotools, so e.g. GNU programs shipped with a bunch of config.h files in a subdirectory and you had to choose the right one. Our SysV was a weird cross-over that didn't quite match anything, so that was ... a very valuable learning experience.
BSD and derivatives were still using <strings.h> at the time and <string.h> and <memory.h> were a SysV thing. When things settled in favor of <string.h> that subsumed mem* functions, <memory.h> became redundant, but for the sake of old programs it was logical to make it just forward to <string.h>.
-uwe
Re: on project management
Date: Tue, 11 Aug 2026 14:43:56 +0300
From: Valery Ushakov <[email protected]>
Message-ID: <[email protected]>| [cc'ing kre@ for the first hand information]
Paul Eggert asked me about this sometime in the early hours of (my)
morning. I remember none of it, but did check the CSRG SCCS
files, and apparently I did create these files for BSD in early Aug 1985 - probably based upon some kind of description of what
was in System V. The actual code distributed with 4.4BSD would
have been Chris Torek's ANSI C rewrite though, perhaps 4.3 as well (I didn't check release dates against SCCS change dates).
I replied to Paul with more details, I saw the reply got to UCLA mail servers, but whether he received it, or it was treated as spam, I have no idea.
I do know that some of the listed recipients of this message will not receive it (@gmail certainly won't, @google probably
not either). Others, who knows? (I never will, I treat bounced
mail as spam, and never see it.)
kre
Re: on project management
Quoted 3 lines · Robert Elz
I replied to Paul with more details, I saw the reply got to UCLA mail servers, but whether he received it, or it was treated as spam, I have no idea.
I got it. Thanks for the trip down memory lane. The amusing thing to me is how 7th Edition Unix got by without a single mem*-style function. When 7th Edition code wanted to (say) copy a block of memory it did so by hand, byte by byte.
Here are you sent me in your email dated Tue, 11 Aug 2026 03:56:27 +0700:
Quoted 95 lines
Date: Mon, 10 Aug 2026 10:29:12 -0700 From: Paul Eggert <[email protected]> Message-ID: <[email protected]>| In an email today[1], Ingo Schwarze mentioned your contribution to | what became 4.3BSD,
There was some of that yes, starting around 3BSD, but:
| a contribution that introduced <
memory.h>.I have no memory of anything related to that, and it sounds kind
of unlikely -- but that is all so long ago. When I look in
the sccs logs ofmemchr.cI see:D 5.5 90/05/15 14:07:06 bostic 5 4 00022/00020/00011
ANSI C version from Chris TorekD 5.4 88/06/27 18:25:34 bostic 4 3 00010/00005/00021
install approved copyright noticeD 5.3 88/05/25 14:23:52 bostic 3 2 00010/00008/00016
written by Robert Elz; add Berkeley specific headerD 5.2 86/03/09 19:33:58 donn 2 1 00001/00001/00023
addedLIBC_SCCScondition for sccs idsD 5.1 85/08/05 21:43:13 kre 1 0 00024/00000/00000
date and time created 85/08/05 21:43:13 by kreso I guess I probably did have something to do with some of it.
The comment at the top (after the copyright nonsense) says:
/*
* Sys5 compat routine
*/It included no header files.
But there was a <
memory.h> created at about the same time:D 5.4 90/05/15 19:43:57 bostic 4 3 00001/00001/00019
string.his ANSI C include fileD 5.3 90/02/12 12:20:39 bostic 3 2 00001/00005/00019
might as well only have one copy.D 5.2 88/08/12 14:13:46 bostic 2 1 00020/00013/00004
correct list from manual pageD 5.1 85/08/05 21:21:49 kre 1 0 00017/00000/00000
date and time created 85/08/05 21:21:49 by kreThe 5.3 change altered it to just be #include <
strings.h> and then the 5.4 change made that <string.h>(In both cases there were later revisions than shown here, but they're mostly just updates for 4.4 type stuff, different copyright/licence, etc, rather than anything substantive).
| Ingo writes that the code's comment "appears to claim that <memory.h> | along with these five functions [memccpy, memcmp, memcpy, memchr, memset] | came from AT&T System V UNIX,"came from" in the sense that SysV created those functions, and then CSRG (me it seems) made BSD implementations - they are all trivial.
85 was probably the year I spent 3 months working at CSRG (I certainly remember there was such a 3 month period - I also remember never bothering to fill in a California Tax return, and recover the (about) $10 refund I
would have had coming... But I no longer actually remember which year that
was.)| almost half a decade before ANSI C 89 standardized them to | live in <
string.h>."Certainly could be - whether SysV used <
memory.h> or whether that was an invention, I have no idea.The comment at the head of that one just says:
/*
* Definitions of the Sys5 compat memory manipulation routines */No indication if SysV used the same file name or not. If I had to guess, I'd suspect possibly so, as I doubt I would have called it "
memory.h" had I been inventing its name - so that probably came from wherever the specs for the functions came from.
,,,
I didn't check the other 4 functions, but if I wrote the initial version ofmemchr()for BSD, it seems likely I wrote the others as well, but the version distributed seems likely to have been Chris Torek's rewrite. My version had K&R C style function definitions.
Re: the Linux man-pages as an educational tool
In reply to G. Branden RobinsonQuoted 5 lines · G. Branden Robinson
Quoted 1 line
The name of a header providing some function is thus inconsequential.
Then why not have one official big header file for the whole standard?
#include <
stdlibc.h>
That wouldn't be too unreasonable nowadays I suppose, not IMHO anyway.
Back when memory was much more constrained in computers it made sense to
have declarations split across many files so as not to have to load and process lots of unnecessary data which could overflow the memory space available. Beyond that the overall performance of contemporary machines is not to be underrated for the purpose of this consideration either.
So yes, I think having one .h file per -l library would make sense now.
FWIW,
Maciej
Re: the Linux man-pages as an educational tool
Hi all!
On 2026-08-14 17:30:17, Maciej W. Rozycki wrote:
[...]
Quoted 5 lines
Quoted 3 lines
Then why not have one official big header file for the whole standard?
#include <
stdlibc.h>That wouldn't be too unreasonable nowadays I suppose, not IMHO anyway.
The trivial counter example is windows.h (since ages). And at one point "they" introduced the #define WIN32_LEAN_AND_MEAN (probably) for a reason ...
[...]
Kind regards,
Bernd
Signature · 3 lines
Bernd Petrovitsch Email : [email protected] There is NO CLOUD, just other people's computers. - FSFE mobile: +43 664 4416156 LUGA : http://www.luga.at
Re: the Linux man-pages as an educational tool
Quoted 9 lines · Bernd Petrovitsch
Quoted 5 lines
Quoted 3 lines
Then why not have one official big header file for the whole standard?
#include <
stdlibc.h>That wouldn't be too unreasonable nowadays I suppose, not IMHO anyway.
The trivial counter example is
windows.h(since ages). And at one point "they" introduced the #defineWIN32_LEAN_AND_MEAN(probably) for a reason ...
I'm not sure what you refer to, is that Microsoft Windows? How would it
be relevant to *nix libc?
Back in 1970s-80s when the C language standard was being shaped computers
had memories in the range of kilobytes and storage was often floppy disks with all the performance implications, plus computing power in the low MHz range. Nowadays we have memory amounts in the high range of gigabytes to terabytes and storage that has throughput of gigabytes per second, and computing power many orders of magnitude better if you factor in not only the clock rate increase, but all the contemporary architectural features as well. How could it not matter for the speed of header compilation?
Maciej
Re: the Linux man-pages as an educational tool
In the limit one could have a single header file for the entire gamut of the C standard and one for Posix. Who can recite even a tiny fraction of all the functions and constants in those sources? Such fat headers overstuff the namespace, making it all too easy to step on accidentally. As a rule of thumb, I'd say a header with a hundred entries stresses the limits.
I don't put much store by arguments about the effect on compilation speed.
Doug
Re: the Linux man-pages as an educational tool
In reply to Maciej W. RozyckiHi! all!
Quoted 1 line · Maciej W. Rozycki
On Fri, 14 Aug 2026, Bernd Petrovitsch wrote:
[...]
Quoted 11 lines
Quoted 9 lines
Quoted 5 lines
Quoted 3 lines
Then why not have one official big header file for the whole standard?
#include <
stdlibc.h>That wouldn't be too unreasonable nowadays I suppose, not IMHO anyway.
The trivial counter example is
windows.h(since ages). And at one point "they" introduced the #defineWIN32_LEAN_AND_MEAN(probably) for a reason ...I'm not sure what you refer to, is that Microsoft Windows? How would it
Yes.
Quoted 1 line
be relevant to *nix libc?
Because M$FT choose the "you need only one #include for all header files" strategy and implicitly admitted that it was not the best idea ....
Quoted 3 lines
Back in 1970s-80s when the C language standard was being shaped computers
had memories in the range of kilobytes and storage was often floppy disks with all the performance implications, plus computing power in the low MHz
Above was more in the late 1980ies/1990ies with harddisks ...
Quoted 5 lines
range. Nowadays we have memory amounts in the high range of gigabytes to terabytes and storage that has throughput of gigabytes per second, and computing power many orders of magnitude better if you factor in not only the clock rate increase, but all the contemporary architectural features as well. How could it not matter for the speed of header compilation?
And we may have "pre-compiled header files" though I never found (or more stumbled upon) a serious page on "how to use them correctly and efficiently" (though I'm not looking for that often).
LG,
Bernd
Signature · 3 lines
Bernd Petrovitsch Email : [email protected] There is NO CLOUD, just other people's computers. - FSFE mobile: +43 664 4416156 LUGA : http://www.luga.at