<html><head></head><body>Hi,<br><br>That text says that you can convert from T* to void* and back. Of course, that's possible. But that patch changes the code so that it converts from T* to void* and then forth.<br><br>Keep in mind that C++ is a piece of s**t where pointer equality is not an equivalence relation, and pointer conversions do not compose.<br><br><div class="gmail_quote">Le 29 avril 2019 18:22:23 GMT+02:00, pierre@videolabs.io a écrit :<blockquote class="gmail_quote" style="margin: 0pt 0pt 0pt 0.8ex; border-left: 1px solid rgb(204, 204, 204); padding-left: 1ex;">
<pre class="k9mail">Hi,<br><br>The C++11 standard states that:<br><br>4.10 - 2 (pointer conversion)<br>A prvalue of type “pointer to cv T,” where T is an object type, can be <br>converted to a pr value of type “pointer to cv void”. The result of <br>converting a “pointer to cv T” to a “pointer to cv void” points to the <br>start of the storage location where the object of type T resides, as if <br>the object is a most derived object (1.8) of type T(that is, not a base <br>class subobject). The null pointer value is converted to the null <br>pointer value of the destination type.<br><br>5.2.9 - 13 (static cast)<br>A pr value of type “pointer to cv1 void” can be converted to a pr value <br>of type “pointer to cv2 T,” where T is an object type and cv2 is the <br>same cv-qualification as, or greater cv-qualification than,cv1. The null <br>pointer value is converted to the null pointer value of the destination <br>type. A value of type pointer to object converted to “pointer to cv <br>void” and back, possibly with different cv-qualification, shall have its <br>original value<br><br>So, if I'm not mistaken, this is OK to cast back and forth to void*<br><br>On 2019-04-29 17:08, Rémi Denis-Courmont wrote:<br><blockquote class="gmail_quote" style="margin: 0pt 0pt 1ex 0.8ex; border-left: 1px solid #729fcf; padding-left: 1ex;">Hi,<br><br>Well I don't challenge that the static cast between derived and base<br>class is valid. But cast to/from void* still seems wrong to me as<br>before.<br><br>Le 29 avril 2019 14:59:23 GMT+02:00, pierre@videolabs.io a écrit :<br><br><blockquote class="gmail_quote" style="margin: 0pt 0pt 1ex 0.8ex; border-left: 1px solid #ad7fa8; padding-left: 1ex;">Hi,<br><br>This patch move    the destruction    of the callback    to the<br>Derived class<br>to    avoid<br>race conditions when the callback is called during the object<br>destruction.<br><br>Note that casting from the base class QVLCVariable to the Derived<br>class<br>is safe with a<br>static_cast as QVLCVariable is a non virtual base classe of Derived.<br><br>hence no<br>pointer fixup is required.<br><br>On 2019-04-29 14:57, Pierre Lamot wrote:<br><blockquote class="gmail_quote" style="margin: 0pt 0pt 1ex 0.8ex; border-left: 1px solid #8ae234; padding-left: 1ex;">children object isn't built yet.<br><br>Fixes #22187<hr>modules/gui/qt/adapters/var_common_p.hpp | 18 +++++++<br>modules/gui/qt/adapters/variables.hpp | 60<br>++++++++++++++++--------<br>2 files changed, 59 insertions(+), 19 deletions(-)<br><br>diff --git a/modules/gui/qt/adapters/var_common_p.hpp<br>b/modules/gui/qt/adapters/var_common_p.hpp<br>index 47f8e89ca1..7ac324739b 100644<br>--- a/modules/gui/qt/adapters/var_common_p.hpp<br>+++ b/modules/gui/qt/adapters/var_common_p.hpp<br>@@ -51,6 +51,8 @@ public:<br>assert(false);<br>}<br><br>+ virtual void clear() {}<br>+<br>operator bool() const {<br>return get() != nullptr;<br>}<br>@@ -81,6 +83,10 @@ public:<br>m_object.reset(vout, hold);<br>}<br><br>+ void clear() override {<br>+ m_object.reset(NULL, false);<br>+ }<br>+<br>private:<br>static void obj_hold( vout_thread_t* obj ) { vout_Hold(obj); }<br>static void obj_release( vout_thread_t* obj ) { vout_Release(obj);<br><br>}<br>@@ -108,6 +114,10 @@ public:<br>m_object = p_intf;<br>}<br><br>+ void clear() override {<br>+ m_object = NULL;<br>+ }<br>+<br>private:<br>intf_thread_t* m_object;<br>};<br>@@ -133,6 +143,10 @@ public:<br>m_object.reset(aout, hold);<br>}<br><br>+ void clear() override {<br>+ m_object.reset(NULL, false);<br>+ }<br>+<br>private:<br>static void obj_hold( audio_output_t* obj ) { aout_Hold(obj); }<br>static void obj_release( audio_output_t* obj ) {<br>aout_Release(obj); }<br>@@ -157,6 +171,10 @@ public:<br>m_object = obj;<br>}<br><br>+ void clear() override {<br>+ m_object = NULL;<br>+ }<br>+<br>private:<br>vlc_object_t *m_object;<br>};<br>diff --git a/modules/gui/qt/adapters/variables.hpp<br>b/modules/gui/qt/adapters/variables.hpp<br>index 710880cf23..c500187c50 100644<br>--- a/modules/gui/qt/adapters/variables.hpp<br>+++ b/modules/gui/qt/adapters/variables.hpp<br>@@ -112,39 +112,26 @@ public:<br>, m_object(new VLCObjectHolderImpl<T>(nullptr))<br>, m_property(property)<br>{<br>- resetObject<T>(object);<br>- Derived* derived = static_cast<Derived*>(this);<br>- connect(derived, &Derived::valueChangedInternal, this,<br>&QVLCVariable<Derived, BaseType>::onValueChangedInternal,<br>Qt::QueuedConnection);<br>}<br><br>virtual ~QVLCVariable()<br>{<br>- if (m_object->get())<br>- {<br>- Derived* derived = static_cast<Derived*>(this);<br>- var_DelCallback(m_object->get(), qtu(m_property),<br>value_modified, derived);<br>- var_Destroy(m_object->get(), qtu(m_property));<br>- }<br>+ assert(m_object->get() == nullptr);<br>}<br><br>///change the object beeing observed<br>template<typename T><br>void resetObject( T* object )<br>{<br>- Derived* derived = static_cast<Derived*>(this);<br>- if (m_object->get()) {<br>- var_DelCallback( m_object->get(), qtu(m_property),<br>value_modified, derived );<br>- var_Destroy(m_object->get(), qtu(m_property));<br>- }<br>-<br>- m_object->reset( object, true );<br>- if (m_object->get())<br>+ clearObject();<br>+ if (object)<br>{<br>+ m_object->reset( object, true );<br>int type = var_Type(object, qtu(m_property));<br>if (type == 0) //variable not found<br>{<br>msg_Warn(m_object->get(), "variable %s not found in<br>object", qtu(m_property));<br>- m_object->reset((T*)nullptr);<br>+ m_object->clear();<br>return;<br>}<br>assert((type & VLC_VAR_CLASS) ==<br>VLCVarTypeTraits<BaseType>::var_type);<br>@@ -154,13 +141,24 @@ public:<br>BaseType value =<br>VLCVarTypeTraits<BaseType>::fromValue(currentvalue);<br>if (m_value != value)<br>{<br>+ Derived* derived = static_cast<Derived*>(this);<br>m_value = value;<br>emit derived->valueChanged( m_value );<br>}<br>}<br><br>var_Create(m_object->get(), qtu(m_property),<br>VLCVarTypeTraits<BaseType>::var_type);<br>- var_AddCallback(m_object->get(), qtu(m_property),<br>value_modified, derived);<br>+ var_AddCallback(m_object->get(), qtu(m_property),<br>value_modified, this);<br>+ }<br>+ }<br>+<br>+ void clearObject()<br>+ {<br>+ if (m_object->get())<br>+ {<br>+ var_DelCallback( m_object->get(), qtu(m_property),<br>value_modified, this );<br>+ var_Destroy(m_object->get(), qtu(m_property));<br>+ m_object->clear();<br>}<br>}<br><br>@@ -221,6 +219,12 @@ public:<br>QVLCBool(T* object, QString property, QObject* parent = nullptr)<br>: QVLCVariable<QVLCBool, bool>(object, property, parent)<br>{<br>+ resetObject<T>(object);<br>+ connect(this, &QVLCBool::valueChangedInternal, this,<br>&QVLCBool::onValueChangedInternal, Qt::QueuedConnection);<br>+ }<br>+<br>+ ~QVLCBool() {<br>+ clearObject();<br>}<br><br>public slots:<br>@@ -241,6 +245,12 @@ public:<br>QVLCString(T* object, QString property, QObject* parent = nullptr)<br>: QVLCVariable<QVLCString, QString>(object, property, parent)<br>{<br>+ resetObject<T>(object);<br>+ connect(this, &QVLCString::valueChangedInternal, this,<br>&QVLCString::onValueChangedInternal, Qt::QueuedConnection);<br>+ }<br>+<br>+ ~QVLCString() {<br>+ clearObject();<br>}<br><br>public slots:<br>@@ -261,6 +271,12 @@ public:<br>QVLCFloat(T* object, QString property, QObject* parent = nullptr)<br>: QVLCVariable<QVLCFloat, float>(object, property, parent)<br>{<br>+ resetObject<T>(object);<br>+ connect(this, &QVLCFloat::valueChangedInternal, this,<br>&QVLCFloat::onValueChangedInternal, Qt::QueuedConnection);<br>+ }<br>+<br>+ ~QVLCFloat() {<br>+ clearObject();<br>}<br><br>public slots:<br>@@ -282,6 +298,12 @@ public:<br>QVLCInteger(T* object, QString property, QObject* parent =<br>nullptr)<br>: QVLCVariable<QVLCInteger, int64_t>(object, property, parent)<br>{<br>+ resetObject<T>(object);<br>+ connect(this, &QVLCInteger::valueChangedInternal, this,<br>&QVLCInteger::onValueChangedInternal, Qt::QueuedConnection);<br>+ }<br>+<br>+ ~QVLCInteger() {<br>+ clearObject();<br>}<br><br>public slots:<br></blockquote><hr>vlc-devel mailing list<br>To unsubscribe or modify your subscription options:<br><a href="https://mailman.videolan.org/listinfo/vlc-devel">https://mailman.videolan.org/listinfo/vlc-devel</a><br></blockquote><br>--<br>Envoyé de mon appareil Android avec Courriel K-9 Mail. Veuillez<br>excuser ma brièveté.<hr>vlc-devel mailing list<br>To unsubscribe or modify your subscription options:<br><a href="https://mailman.videolan.org/listinfo/vlc-devel">https://mailman.videolan.org/listinfo/vlc-devel</a><br></blockquote><br></pre></blockquote></div><br>-- <br>Envoyé de mon appareil Android avec Courriel K-9 Mail. Veuillez excuser ma brièveté.</body></html>