When running code in C++, remove the macro which is applying regardless
of the language context, and provide dedicated function overload for the
same effect. In addition, provide a dedicated wrapper avoiding cast and
size specification.
Like done by _Generic in the C version, use overloading functions to
define the correct casting behaviour depending on whether the pointer
is already a vlc_object_t or possess a vlc_object_t as ->obj.
This removes the need for listing all the objects which need a casting
case, and non-vlc_object_t objects will fail with the following error:
include/vlc_objects.h: In instantiation of ‘vlc_object_t* VLC_OBJECT(T*) [with T = {anonymous}::demux_sys_t; vlc_object_t = vlc_object_t]’:
include/vlc_objects.h:83:18: error: ‘struct {anonymous}::demux_sys_t’ has no member named ‘obj’
or, if there is a obj field which is not a vlc_object_t:
include/vlc_objects.h: In instantiation of ‘vlc_object_t* VLC_OBJECT(T*) [with T = Open(vlc_object_t*)::foo; vlc_object_t = vlc_object_t]’:
include/vlc_objects.h:83:18: error: cannot convert ‘Open(vlc_object_t*)::foo::obj*’ to ‘vlc_object_t*’ in return
83 | { return &d->obj; }
| ~~~^~~
| |
| Open(vlc_object_t*)::foo::obj*
Objects have one strong reference held by their "owner", and zero or
more weak references generated by vlc_object_hold() et al. This
provides a separate function to remove the strong reference than
vlc_object_release() to remove weak ones.
With this sole change, this is really only an annotation though.
At this point, this merely avoids iterating up the objects tree to log
messages. Effectively, the logger pointer takes the place of the libvlc
instance pointer.
Going forward, this should be usable to override logging on a sub-tree.
If the offset of b within a is zero, then (&(a)->b) is equivalent to
casting a to a pointer to the type of the b member. However this implies
that a is a valid pointer. The expression is not valid if a is NULL.
Especially sanitizers do not like this.