On 2018-02-24 21:57, Eric Blake wrote: > On 02/24/2018 09:40 AM, Max Reitz wrote: >> This is a dynamic casting macro that, given a QObject type, returns an >> object as that type or NULL if the object is of a different type (or >> NULL itself). >> >> The macro uses lower-case letters because: >> 1. There does not seem to be a hard rule on whether qemu macros have to >> be upper-cased, >> 2. The current situation in qapi/qmp is inconsistent (compare e.g. >> QINCREF() vs. qdict_put()), >> 3. qobject_to() will evaluate its @obj parameter only once, thus it is >> generally not important to the caller whether it is a macro or not, >> 4. I prefer it aesthetically. >> >> Signed-off-by: Max Reitz <mre...@redhat.com> >> --- >> include/qapi/qmp/qobject.h | 30 ++++++++++++++++++++++++++++++ >> 1 file changed, 30 insertions(+) >> > >> +++ b/include/qapi/qmp/qobject.h >> @@ -50,6 +50,22 @@ struct QObject { >> #define QDECREF(obj) \ >> qobject_decref(obj ? QOBJECT(obj) : NULL) >> +/* Required for qobject_to() */ >> +#define QTYPE_CAST_TO_QNull QTYPE_QNULL >> +#define QTYPE_CAST_TO_QNum QTYPE_QNUM >> +#define QTYPE_CAST_TO_QString QTYPE_QSTRING >> +#define QTYPE_CAST_TO_QDict QTYPE_QDICT >> +#define QTYPE_CAST_TO_QList QTYPE_QLIST >> +#define QTYPE_CAST_TO_QBool QTYPE_QBOOL >> + >> +QEMU_BUILD_BUG_MSG(QTYPE__MAX != 7, >> + "The QTYPE_CAST_TO_* list needs to be extended"); >> + >> +#define qobject_to(obj, type) \ >> + container_of(qobject_check_type(obj, glue(QTYPE_CAST_TO_, type)) >> ?: \ >> + QOBJECT((type *)NULL), \ > > I guess the third (second?) branch of the ternary is written this way, > rather than the simpler 'NULL', to ensure that 'type' is still something > that can have the QOBJECT() macro applied to it? Should be okay.
It's written this way because of the container_of() around it. We want the whole expression to return NULL then, and without the QOBJECT() around it, it would only return NULL if offsetof(type, base) == 0 (which it is not necessarily). OTOH, container_of(&((type *)NULL)->base, type, base) is by definition NULL. (QOBJECT(x) is &(x)->base) Max > >> + type, base) >> + > > Reviewed-by: Eric Blake <ebl...@redhat.com> >
signature.asc
Description: OpenPGP digital signature