free(3) const void *
Arsen Arsenović
arsen@gentoo.org
Fri Jan 26 20:04:53 GMT 2024
Hi Alex,
Alejandro Colomar <alx@kernel.org> writes:
> [[PGP Signed Part:No public key for 9E8C1AFBBEFFDB32 created at 2024-01-26T19:11:27+0100 using RSA]]
> Hi Xi,
>
> On Sat, Jan 27, 2024 at 01:55:48AM +0800, Xi Ruoyao wrote:
>> In C we (not sure about the people, but at least the compiler) cannot
>> rely on it at all. It's perfectly legal to write something like
>>
>> void
>> stupid (const char *c)
>> {
>> strcpy ((char *)c, "some bullshit");
>> }
>>
>> int
>> main (void)
>> {
>> char buf[100];
>> stupid (buf);
>> puts (buf);
>> }
>>
>> Yes it's as stupid as the name of the function. But it does *not*
>> invoke any undefined behavior, and so the compiler is not allowed to do
>> any optimization assuming "stupid" won't change the content in buf.
>>
>> That's why GCC has invented __attribute__ ((access (read_only, ...))).
>> The documentation of this attribute even says we cannot rely on the
>> const qualifier:
>>
>> The read_only access mode specifies that the pointer to which it
>> applies is used to read the referenced object but not write to it.
>> Unless the argument specifying the size of the access denoted by
>> size-index is zero, the referenced object must be initialized. The
>> mode implies a stronger guarantee than the const qualifier which,
>> when cast away from a pointer, does not prevent the pointed-to object
>> from being modified. Examples of the use of the read_only access mode
>> is the argument to the puts function, or the second and third
>> arguments to the memcpy function.
>
> Thanks!
>
> This reminds me of access(none), which is the strongest of the access
> modes that [[gnu::access()]] has. free(3) could perfectly use
> [[gnu::access(none)]], since it neither needs to read nor write to the
> pointee. That is stronger than const, so slapping a const there should
> be straight-forward.
>
> Regarding Andreas's consideration that libc functions are a black box:
> free(3) as a black box means that the lifetime of the object is
> terminated at the function boundary, so for the abstract machine,
> free(3) cannot possibly access the object (since there's no object
> any more). If it does, for implementation-defined reasons, that
> shouldn't be a problem of the caller, and libc should discard const
> internally.
Note that the library (and implementation more broadly) are exempt from
various bits of the standard, as they are expected to be magic.
Notably, the 'lifetime ends at free boundary' rule doesn't mean that
free can't access the object in whichever way it pleases (and, in fact,
free already fails to comply with various other lifetime-related
definitions, to my knowledge).
> Have a lovely night! =)
> Alex
--
Arsen Arsenović
More information about the Libc-alpha
mailing list