vlc_objects: expose wrappers around vlc_object_create/delete

Using placement new and manual call to the destructor. It ensures that
C++ objects are correctly handled when creating C++ objects through
vlc_object_create<>(), and that their destructors are correctly called
when the (C++) object is destroyed.

According to the C++ draft standard, the vlc_object_t won't get
overwritten by the placement new since (7.1) will apply to the C++
object being allocated and placement-new'ed, which triggers the default
initialization of members, and the default initialization of the
vlc_object_t member enters the (7.3) case since no constructors exists
for the structure. (It's an extern "C" structure).

    To default-initialize an object of type T means:
    (7.1)
    If T is a (possibly cv-qualified) class type ([class]), constructors are considered.
    The applicable constructors are enumerated ([over.match.ctor]), and the best one for the initializer () is chosen through overload resolution ([over.match]).
    The constructor thus selected is called, with an empty argument list, to initialize the object.
    (7.2)
    If T is an array type, each element is default-initialized.
    (7.3)
    Otherwise, no initialization is performed.
    --: https://eel.is/c++draft/dcl.init#general-7

However, it's not possible to use a zero-initializing placement-new
operation.
This commit is contained in:
Alexandre Janniaux 2023-12-20 16:26:52 +01:00 committed by Thomas Guillem
parent 1701e2da5c
commit 6cfbabfc55
1 changed files with 16 additions and 1 deletions

View File

@ -24,6 +24,7 @@
#define VLC_OBJECTS_H 1
#ifdef __cplusplus
#include <new>
extern "C" {
#endif
@ -314,8 +315,22 @@ template<typename T, typename O> VLC_MALLOC VLC_USED
static inline T* vlc_object_create(O *obj)
{
static_assert(std::is_pointer<T>::value == false, "vlc_object_create can only create objects");
return static_cast<T*>(vlc_object_create(VLC_OBJECT(obj), sizeof(T)));
void *object = vlc_object_create(VLC_OBJECT(obj), sizeof(T));
if (object == nullptr)
return nullptr;
return new(object) T;
}
#undef vlc_object_delete
template<typename O>
static inline void vlc_object_delete(O *obj)
{
if (!std::is_trivially_destructible<O>::value)
obj->~O();
vlc_object_delete(VLC_OBJECT(obj));
}
#endif
/** @} */