On 9/18/19 1:05 PM, Eric Blake wrote:

>>> #define MAKE_ERRP_SAFE() \
>>> g_auto(ErrorPropagationStruct) (__auto_errp_prop) = {.errp = errp}; \
>>> errp = &__auto_errp_prop.local_err
>>>

I tried to see if this could be done with just a single declaration
line, as in:

typedef struct ErrorPropagator {
    Error **errp;
    Error *local_err;
} ErrorPropagator;

#define MAKE_ERRP_SAFE() \
  g_auto(ErrorPropagator) __auto_errp_prop = { \
    errp, ((errp = &__auto_errp_prop.local_err), NULL) }

But sadly, C17 paragraph 6.7.9P23 states:

"The evaluations of the initialization list expressions are
indeterminately sequenced with respect to one another and thus the order
in which any side effects occur is unspecified."

which does not bode well for the assignment to __auto_errp_prop.errp.
All changes to errp would have to be within the same initializer.  Maybe:

#define MAKE_ERRP_SAFE() \
  g_auto(ErrorPropagator) __auto_errp_prop = { \
    .local_err = (__auto_errp_prop.err = errp, \
        (errp = &__auto_errp_prop.local_err), NULL) }

but by the time you get that complicated, just using a statement is
easier to read.

-- 
Eric Blake, Principal Software Engineer
Red Hat, Inc.           +1-919-301-3226
Virtualization:  qemu.org | libvirt.org

Reply via email to