From: Russ Allbery <eagle@eyrie.org>
To: Alejandro Colomar <alx@kernel.org>
Cc: libc-alpha@sourceware.org
Subject: Re: free(3) const void *
Date: Fri, 26 Jan 2024 10:09:35 -0800 [thread overview]
Message-ID: <87y1ccq84g.fsf@hope.eyrie.org> (raw)
In-Reply-To: <ZbOx0LHbQclQorst@debian> (Alejandro Colomar's message of "Fri, 26 Jan 2024 14:21:13 +0100")
Alejandro Colomar <alx@kernel.org> writes:
> Since a `const void *` will accept anything that a `void *` would accept
> (and more), how about changing the prototype of free() in glibc as an
> extension to the language?
> I'd like to refor free(3) to be:
> void free(const void *p);
Maybe this way of explaining the objection will help. Right now, if you
pass a const pointer into a function, you have some assurance from that
prototype (assisted by compiler diagnostics) that this function will not
modify *or invalidate* that pointer and you can continue using that
pointer after that call. In other words, while C does not have full
Rust-style lifetime tracking, the const marker on a function approximately
indicates that the caller is not passing ownership of the pointer to that
function and the function call will not affect the pointer.
With this prototype, I believe you will create a situation where someone
could write a function that takes a const pointer and then calls free() at
the end of that function call on this passed parameter, and there would be
no warning from the compiler either when compiling that function or when
compiling a function that calls it and then uses the pointer afterwards
(at least unless there is enough inlining that a compiler can put all the
pieces together).
Unless I'm missing something, the more specific annotation indicating that
free() is a deallocator doesn't help because it doesn't propagate up the
call stack. It will catch use after free within the same function, but it
won't catch the case where someone passes a const pointer down a whole
chain of functions that take const pointers, and then the function at the
bottom of that call stack frees the pointer, unless someone carefully
annotates every function in that call stack with that annotation. When
this is done in error, someone obviously wouldn't do that.
The unique functionality of const here is that it *does* propagate up the
call stack via compiler warnings, in that you can't pass a const pointer
to a function with a non-const prototype without a compiler warning or an
explicit cast. That provides some assurance of those lifetime properties.
In that view of the meaning of const, free() is definitely not const,
since it invalidates the pointer you pass into it and thus by definition
takes ownership of the pointer. I realize this is not the precise
standard definition of const, but it is definitely what a lot of
real-world C code uses const to mean, and right now it basically works.
--
Russ Allbery (eagle@eyrie.org) <https://www.eyrie.org/~eagle/>
next prev parent reply other threads:[~2024-01-26 18:09 UTC|newest]
Thread overview: 33+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-01-26 13:21 Alejandro Colomar
2024-01-26 14:24 ` Arsen Arsenović
2024-01-26 15:35 ` Alejandro Colomar
2024-01-26 17:22 ` Arsen Arsenović
2024-01-26 17:55 ` Xi Ruoyao
2024-01-26 18:11 ` Alejandro Colomar
2024-01-26 20:04 ` Arsen Arsenović
2024-01-26 20:07 ` Arsen Arsenović
2024-01-26 17:40 ` Andreas Schwab
2024-01-26 19:45 ` Florian Weimer
2024-01-26 15:13 ` Andreas Schwab
2024-01-26 15:33 ` Alejandro Colomar
2024-01-26 18:09 ` Russ Allbery [this message]
2024-01-26 18:23 ` Alejandro Colomar
2024-01-26 18:36 ` Xi Ruoyao
2024-01-26 18:40 ` Alejandro Colomar
2024-01-26 18:49 ` Xi Ruoyao
2024-01-26 18:57 ` Alejandro Colomar
2024-01-26 18:40 ` Russ Allbery
2024-01-26 18:45 ` Alejandro Colomar
2024-01-26 19:41 ` Florian Weimer
2024-01-26 18:39 ` [PATCH] Use [[gnu::access(none)]] on free(3) Alejandro Colomar
2024-01-26 18:41 ` Alejandro Colomar
2024-01-26 21:23 ` Paul Eggert
2024-01-26 23:19 ` Alejandro Colomar
2024-01-27 13:21 ` Cristian Rodríguez
2024-02-13 15:19 ` Gabriel Ravier
2024-02-13 15:28 ` Alejandro Colomar
2024-01-26 21:11 ` free(3) const void * DJ Delorie
2024-01-26 21:30 ` Andreas Schwab
2024-01-26 21:47 ` DJ Delorie
2024-01-26 22:07 ` Andreas Schwab
2024-01-26 23:25 ` 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=87y1ccq84g.fsf@hope.eyrie.org \
--to=eagle@eyrie.org \
--cc=alx@kernel.org \
--cc=libc-alpha@sourceware.org \
/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;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).