Sujet : Re: So You Think You Can Const?
De : 643-408-1753 (at) *nospam* kylheku.com (Kaz Kylheku)
Groupes : comp.lang.cDate : 10. Jan 2025, 20:28:22
Autres entêtes
Organisation : A noiseless patient Spider
Message-ID : <20250110111155.648@kylheku.com>
References : 1 2 3
User-Agent : slrn/pre1.0.4-9 (Linux)
On 2025-01-09, David Brown <
david.brown@hesbynett.no> wrote:
On 08/01/2025 17:48, Andrey Tarasevich wrote:
>
It is perfectly safe. One can even argue that standard declaration if
`free` as `void free(void *)` is defective. It should have been `void
free(const void *)` from the very beginning.
>
It is common in simple heap implementations for the allocated block to
contain data about the block, such as allocation sizes and pointers to
other blocks, in memory just below the address returned by malloc.
free() then uses its parameter to access that data, and may change it.
So "void free(const void *);" would be lying to the user.
If the pointer came from the allocator, as required, there is no lie.
The object is writable, and so free may strip away the qualifier
and do whatever it wants, like cover the object with 0xFE bytes.
Quite contrary, if the program calls free(p), yet still somehow cares
about what happens to the contents referenced by p, then the program is
lying to the implementation!
The prototype of free being: void free(const void *) would be helpful.
It would mean that programs which choose to initialize dynamically
allocated objects and then pass them around via pointers to const could
then free the objects without having to use a cast.
Code like this can be free of casts:
const obj *obj_create(int param)
{
obj *o = malloc(sizeof *po); // null check omitted for topic focus
o->param = param;
return o; // after this, objs treated as immutable
}
void obj_destroy(const obj *o)
{
free(o);
}
Free of casts is good!
Might it already be that the features of the current ISO C standard
allow for the possibility of free being generic betwen const and
unqualified? Though I don't suspect you can select on a pointer's
referenced type's qualification, regardless of type.
What are the backward compatibilty considerations of just making
the prototype void free(const void *)?
One is this problem:
void (*pfree)(void *) = free;
but in fact, the type rules should be such that the assignment
is allowed even if free is void(const void *).
The type compatibility rule should be that a function pointer type with
more strictly qualified parameters should be implicitly convertible to a
function pointer type with less strictly qualified parameters.
-- TXR Programming Language: http://nongnu.org/txrCygnal: Cygwin Native Application Library: http://kylheku.com/cygnalMastodon: @Kazinator@mstdn.ca