In addition to Eric's comments... Marc-André Lureau <marcandre.lur...@redhat.com> writes:
> By moving the base fields to a QObjectBase_, QObject can be a type > which also has a 'base' field. This allows to write a generic > QOBJECT() macro that will work with any QObject type, including > QObject itself. The container_of() macro ensures that the object to > cast has a QObjectBase_ base field, giving some type safety > guarantees. QObject must have no members but QObjectBase_ base, or > else QOBJECT() breaks. > > QObjectBase_ is not typedef and use a trailing underscore to make it > obvious it is not for normal use and to avoid potential abuse. > > Signed-off-by: Marc-André Lureau <marcandre.lur...@redhat.com> [...] > diff --git a/include/qapi/qmp/qobject.h b/include/qapi/qmp/qobject.h > index 5206ff9ee1..0a7f800d58 100644 > --- a/include/qapi/qmp/qobject.h > +++ b/include/qapi/qmp/qobject.h > @@ -34,13 +34,20 @@ > > #include "qapi/qapi-builtin-types.h" > > -struct QObject { > +/* Not for use outside include/qapi/qmp/ */ > +struct QObjectBase_ { > QType type; > size_t refcnt; > }; > > -/* Get the 'base' part of an object */ > -#define QOBJECT(obj) (&(obj)->base) > +struct QObject { > + struct QObjectBase_ base; > +}; > + > +#define QOBJECT(x) ({ \ > + typeof(x) __x = (x); \ > + __x ? container_of(&(__x)->base, QObject, base) : NULL; \ > +}) Identifiers that begin with double underscores are reserved for any use. Drop one of the two, please. > > /* High-level interface for qobject_incref() */ > #define QINCREF(obj) \ > @@ -68,8 +75,8 @@ QEMU_BUILD_BUG_MSG(QTYPE__MAX != 7, > static inline void qobject_init(QObject *obj, QType type) > { > assert(QTYPE_NONE < type && type < QTYPE__MAX); > - obj->refcnt = 1; > - obj->type = type; > + obj->base.refcnt = 1; > + obj->base.type = type; > } > > /** [...]