> I would like to propose an additional, perhaps controversial, use. > 5 Breaking the flow of control:
> #ifdef K5BAIL(x) do { > ret = x; > if (ret) { > /* format error message and whatnot > * in terms of #x. > */ > > goto bail; > } > } while (0) > You can't do this with an inline function, because it can't use goto > or return. If you're willing to commit to gcc - which I gather is the case, if we're even discussing gccisms like __attribute__((__always_inline__)) - then you can do it really easily and relatively elegantly (relative to the other ways, that is) with a nested function and a nonlocal goto: void something_hairy(...) { __label__ bail_to; ...variable declarations... auto void bail(const char *, ...) __attribute__((__format__(__printf__,1,2),__noreturn__)); auto void bail(const char *fmt, ...) { va_list ap; va_start(ap,fmt); ... va_end(ap); goto bail_to; } if (0) { bail_to:; if (thing1) cleanup_thing1(); if (thing2) cleanup_thing2(); ... return; } thing1 = 0; thing2 = 0; ... thing1 = new_thing1(); if (...failure...) bail("can't do it: %d < %d (from %s)",...); ... } (Okay, that's not quite true. Using always_inline doesn't necessarily mean committing to gcc. But _depending on_ always_inline does, ISTM.) /~\ The ASCII Mouse \ / Ribbon Campaign X Against HTML mo...@rodents-montreal.org / \ Email! 7D C8 61 52 5D E7 2D 39 4E F1 31 3E E8 B3 27 4B