18.09.2019 21:32, Eric Blake wrote: > 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) }
Is it guaranteed that .errp will not be initialized to NULL after evaluating of .local_err initializer? > > but by the time you get that complicated, just using a statement is > easier to read. > -- Best regards, Vladimir