public inbox for linux-man@vger.kernel.org
 help / color / mirror / Atom feed
From: Alejandro Colomar <alx@kernel.org>
To: Seth McDonald <sethmcmail@pm.me>
Cc: linux-man@vger.kernel.org
Subject: History of const in C++, C89, and POSIX.1-1988 (was: [PATCH v1 02/19] man/man2/access.2: HISTORY: Specify different)
Date: Tue, 20 Jan 2026 14:52:22 +0100	[thread overview]
Message-ID: <aW96GgzoYUurH5FS@devuan> (raw)
In-Reply-To: <aW9xYhsFpNxlo3C5@McDaDebianPC>

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

Hi Seth,

On Tue, Jan 20, 2026 at 12:13:32PM +0000, Seth McDonald wrote:
> On Tue, Jan 20, 2026 at 02:34:08AM +0100, Alejandro Colomar wrote:
> > Hi Seth,
> > 
> > On Mon, Jan 19, 2026 at 11:55:06AM +0000, Seth McDonald wrote:
> > > access(2) was specified in POSIX.1-1988 with the prototype
> > > int access(char *path, int amode); [1]
> > > 
> > > POSIX.1-1990 then changed the prototype to
> > > int access(const char *path, int amode); [2]
> > 
> > I suspect this is common to all APIs specified in those standards,
> > right?  Or is it specific to this API?
> > 
> > 'const' was invented by ANSI C89, so I expect the change was around that
> > time.
> 
> I believe the qualifier is indeed absent from any* specified prototype
> in POSIX.1-1988.  Which would make sense if it was first specified in
> C89.  Similar to how void pointers didn't first appear in POSIX.1-1988,
> but after being added in C89, appeared in POSIX.1-1990.
> 
> *Interestingly enough, the appendix of POSIX.1-1988 (section B.2.2.4,
> page 192) does acknowledge the const qualifier when describing the C
> Standard's atoi(3) function.  Which makes me think that POSIX was
> actually aware of C89's upcoming additions to the language.  Which in
> turn begs the question: why, if they knew about it, was it not used in
> the POSIX.1-1988 standard?  Multiple other types and functions were
> included in POSIX.1-1988 because they were (going to be) in C89.

I don't know the year in which const was added to the C89 drafts, but
I suspect it was near the release.

The C89 rationale says:

	The syntax and semantics of const were adapted from C++;
	the concept itself has appeared in other languages.

Also, qualifier rules were made more strict near the release of C89, as
they discovered the dangers of assigning a 'char**' to a 'const char**'
near the release.  C++ had more time to investigate the issue before
C++98, and so the came up with the better rules they have.

C2y will likely adopt the C++ rules for qualifiers, as proposed (by me)
in n3749 <https://www.open-std.org/jtc1/sc22/wg14/www/docs/n3749.txt>.
We will vote this in a month or two.

And after we vote n3749, we want to improve the rules even further, as
proposed by Chris Bazley in n3674
<https://www.open-std.org/jtc1/sc22/wg14/www/docs/n3674.pdf>.

> This is just me thinking out loud here.  I don't mind if the answer
> isn't known.  Although if the answer is relevant/broad enough, it may be
> useful to mention it in standards(7).

We might need a qualifiers(7) manual page.  Especially, once their rules
are modified in ISO C2y.  Alternatively, we may need a new section
man3qual, with an intro(3qual) page talking about this, and then
const(3qual) and volatile(3qual) to document the usual qualifiers, plus
a restrict(3qual) documenting how irremediably broken that monster is,
and _Atomic(3qual) also documenting that qualifier (which I never really
understood well, and from what the committee is talking now, they don't
seem to like it either).

> Something like "POSIX.1-1988
> attempted to align its specification with the features/syntax of the
> (not yet released) C89 standard, but for ABC reasons, could not use XYZ
> language features."
> 
> > On the change itself, it wasn't a breaking change: programs written
> > before the addition of const wouldn't notice that const has been added
> > to the prototype.
> > 
> > The change would be noticed by a program written today, but compiled in
> > such an old system.  However, I expect such a program to be aware that
> > pre-ANSI C was different, and it would have to adapt to it anyway.
> > const would be something that would have to be globally ignored, with
> > something like
> > 
> > 	#define const
> > 
> > Given this should be of no importance to users, I'd prefer not
> > documenting this difference.
> > 
> > What do you think?
> 
> It's important to note that since the type 'const char*' is a pointer to
> a const char, rather than a const pointer to a char, the type is
> incompatible with its non-const counterpart.  That is, 'const char*' and
> 'char*' are technically incompatible datatypes.
> 
> This can be seen by attempting to compile the following C program:
> 
> 	#include <stdio.h>
> 
> 	int say_hi(const char* str)
> 	{
> 		return printf("Hi %s", str);
> 	}
> 
> 	int main(void)
> 	{
> 		int (*func)(char*) = say_hi;
> 		func("Linux");
> 		return 0;
> 	}
> 
> On GCC at least, you should get an incompatible-pointer-types error.
> 
> Now imagine an old program that was built to be compatible with
> specifically POSIX.1-1988, and which liked to use function pointers a
> little too much.  If it happened to use function pointers to functions
> whose parameters weren't const-qualified in POSIX.1-1988, but were in
> later versions, then it (to my understanding) cannot be linked to an
> implementation of a later POSIX version without either errors or the
> possibility of undefined behaviour.
> 
> While I cannot guarantee that such a program exists, what I can say is
> that I have used pointers to library functions in my own code before.
> So I don't think it'd be unusual for such a program to exist.
> 
> Given this, I do think this still may be notable enough to document.
> Perhaps not in every such function - as that can get quite repetitive -
> but instead as a property of the POSIX.1-1988 standard as a whole.  But
> feel free to let me know if there's something I missed here.

I suspect back then this was not a big problem.

Function prototypes were also invented by C89 (although it seems to have
been invented in an earlier draft than const, by the fact that
POSIX.1-1988 has prototypes but not const).

Before function prototypes, functions were declared as

	int f();

and function pointers were declared as

	int (*fp)();

For example, here's how qsort(3) was implemented in 4.3BSD (1986):

	alx@devuan:~/src/unix/unix/4.3BSD$ cat ./usr/src/lib/libc/gen/qsort.c \
	| sed -n \
		-e '/^qsort/,/^{/p' \
		-e '/compar\>/p' \
		-e '/qcmp/p' \
		-e '/^}/{p;q}' \
	| uniq;
	static  int		(*qcmp)();		/* the comparison routine */
	qsort(base, n, size, compar)
		char	*base;
		int	n;
		int	size;
		int	(*compar)();
	{
		qcmp = compar;
			if (qcmp(j, lo) > 0)
			while (qcmp(hi -= qsz, min) > 0)
	}

Even though in 1988 function prototypes already existed, I expect code
didn't start using them quickly, and thus no real incompatibilities
existed.

About when function prototypes were introduced...  POSIX.1-1988 already
uses them, and SVID Issue 2 (~1986) doesn't, so it was somewhere between
those years.


Have a lovely day!
Alex

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

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

  reply	other threads:[~2026-01-20 13:52 UTC|newest]

Thread overview: 28+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-01-19 11:54 [PATCH v1 00/19] man/man2/*: Update history of syscalls A-CH Seth McDonald
2026-01-19 11:54 ` [PATCH v1 01/19] man/man2/access.2: HISTORY: Update first POSIX appearance of access(2) Seth McDonald
2026-01-19 11:55 ` [PATCH v1 02/19] man/man2/access.2: HISTORY: Specify different access(2) prototypes Seth McDonald
2026-01-20  1:34   ` Alejandro Colomar
2026-01-20 12:13     ` Seth McDonald
2026-01-20 13:52       ` Alejandro Colomar [this message]
2026-01-20 13:59         ` History of const in C++, C89, and POSIX.1-1988 (was: [PATCH v1 02/19] man/man2/access.2: HISTORY: Specify different) Alejandro Colomar
2026-01-21  6:12         ` Seth McDonald
2026-01-21 14:41           ` On restrict (a broken qualifier) Alejandro Colomar
2026-01-21 14:44           ` History of const in C++, C89, and POSIX.1-1988 (was: [PATCH v1 02/19] man/man2/access.2: HISTORY: Specify different) Alejandro Colomar
2026-01-19 11:55 ` [PATCH v1 03/19] man/man2/access.2: HISTORY: Update first POSIX appearance of faccessat(2) Seth McDonald
2026-01-19 11:55 ` [PATCH v1 04/19] man/man2/alarm.2: HISTORY: Update first POSIX appearance of alarm(2) Seth McDonald
2026-01-19 11:55 ` [PATCH v1 05/19] man/man2/chdir.2: HISTORY: Split chdir(2) and fchdir(2) Seth McDonald
2026-01-19 11:55 ` [PATCH v1 06/19] man/man2/chdir.2: HISTORY: Update first POSIX appearance of chdir(2) Seth McDonald
2026-01-19 11:56 ` [PATCH v1 07/19] man/man2/chdir.2: HISTORY: Specify different chdir(2) prototypes Seth McDonald
2026-01-19 11:56 ` [PATCH v1 08/19] man/man2/chdir.2: HISTORY: Update first POSIX appearance of fchdir(2) Seth McDonald
2026-01-19 11:56 ` [PATCH v1 09/19] man/man2/chmod.2: HISTORY: Split chmod(2) and fchmod(2) Seth McDonald
2026-01-19 11:56 ` [PATCH v1 10/19] man/man2/chmod.2: HISTORY: Update first POSIX appearance of chmod(2) Seth McDonald
2026-01-19 11:57 ` [PATCH v1 11/19] man/man2/chmod.2: HISTORY: Specify different chmod(2) prototypes Seth McDonald
2026-01-19 11:57 ` [PATCH v1 12/19] man/man2/chmod.2: HISTORY: Update first POSIX appearance of fchmod(2) Seth McDonald
2026-01-19 11:57 ` [PATCH v1 13/19] man/man2/chmod.2: HISTORY: Update first POSIX appearance of AT_SYMLINK_NOFOLLOW Seth McDonald
2026-01-19 11:57 ` [PATCH v1 14/19] man/man2/chown.2: HISTORY: Split chown(2), fchown(2), and lchown(2) Seth McDonald
2026-01-19 11:57 ` [PATCH v1 15/19] man/man2/chown.2: HISTORY: Update first POSIX appearance of chown(2) Seth McDonald
2026-01-19 11:58 ` [PATCH v1 16/19] man/man2/chown.2: HISTORY: Specify different chown(2) prototypes Seth McDonald
2026-01-19 11:58 ` [PATCH v1 17/19] man/man2/chown.2: HISTORY: Update first SUS appearance of fchown(2) Seth McDonald
2026-01-19 11:58 ` [PATCH v1 18/19] man/man2/chown.2: HISTORY: Update first POSIX appearance of lchown(2) Seth McDonald
2026-01-19 11:58 ` [PATCH v1 19/19] man/man2/chroot.2: HISTORY: Update first SUS appearance of chroot(2) Seth McDonald
2026-01-20  1:50 ` [PATCH v1 00/19] man/man2/*: Update history of syscalls A-CH Alejandro Colomar

Reply instructions:

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

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

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

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

  git send-email \
    --in-reply-to=aW96GgzoYUurH5FS@devuan \
    --to=alx@kernel.org \
    --cc=linux-man@vger.kernel.org \
    --cc=sethmcmail@pm.me \
    /path/to/YOUR_REPLY

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

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