[FFmpeg-devel] [PATCH 1/3] lavformat: Prepare to make avio_enum_protocols const correct

Andreas Rheinhardt andreas.rheinhardt at gmail.com
Wed Aug 21 13:51:00 EEST 2019


Tomas Härdin:
> ons 2019-08-21 klockan 11:04 +0200 skrev Andreas Rheinhardt:
>> Using avio_enum_protocols works as follows: One initializes a pointer to
>> void and gives avio_enum_protocols the address of said pointer as
>> argument; the pointer will be updated to point to a member of the
>> url_protocols array. Now the address of the pointer can be reused for
>> another call to avio_enum_protocols.
>> Said array consists of constant pointers (to constant URLProtocols),
>> but the user now has a pointer to non-const to it; of course it was always
>> intended that the user is not allowed to modify what the pointer points
>> to and this has been enforced by hiding the real type of the underlying
>> object. But it is better to use a const void ** as parameter to enforce
>> this. This way avio_enum_protocols can be implemented without resorting
>> to casting a const away or ignoring constness as is done currently.
>>
>> Given that this amounts to an ABI and API break, this can only be done
>> at the next major version bump; as usual, the break is currently hidden
>> behind an appropriate #if.
> 
> I'm fairly sure this is only an API break. C ABI doesn't care about
> constness. But also:
> >> @@ -805,7 +805,11 @@ int avio_close_dyn_buf(AVIOContext *s, uint8_t
**pbuffer);
>>   *
>>   * @return A static string containing the name of current protocol or NULL
>>   */
>> +#if FF_API_NONCONST_ENUM_PROTOCOLS
>>  const char *avio_enum_protocols(void **opaque, int output);
>> +#else
>> +const char *avio_enum_protocols(const void **opaque, int output);
>> +#endif
> 
> This should still be perfectly compatible with all user code since
> adding const is fine..
> 
No. void* can be safely and automatically converted to const void*;
and the conversion from void** to void * const * is fine, too, but the
conversion from void ** to const void ** is not safe for the reason
already mentioned. I'll explain it once more. Imagine
avio_enum_protocols already used a const void ** parameter and were
const-correct and we called the function in the following way:

void *opaque = NULL;
avio_enum_protocols(&opaque, 0);

opaque now points to something const (namely the first element of the
url_protocols array, an array of const pointers (to constant
URLProtocols)), but opaque is not a pointer to something const, i.e. a
violation of the const system has happened. Therefore one needs an
explicit cast for this unsafe conversion; or the compiler complains.
It is of course easy to fix this: Simply declare opaque as const void
*. As mentioned already, the caller has no business modifying what
this pointer points to anyway.

- Andreas


More information about the ffmpeg-devel mailing list