Hi, On Sunday, September 16, 2012 04:23:14 PM Andres Freund wrote: > What do you think about something like: > > typedef struct dlist_iter > { > /* > * Use a union with equivalent storage as dlist_node to make it possible > to * initialize the struct inside a macro without multiple evaluation. */ > union { > struct { > dlist_node *cur; > dlist_node *end; > }; > dlist_node init; > }; > } dlist_iter; > > typedef struct dlist_mutable_iter > { > union { > struct { > dlist_node *cur; > dlist_node *end; > }; > dlist_node init; > }; > dlist_node *next; > } dlist_mutable_iter; > > #define dlist_iter_foreach(iter, ptr) > \ > for (iter.init = (ptr)->head; iter.cur != iter.end; > \ > iter.cur = iter.cur->next) > > #define dlist_iter_foreach_modify(iter, ptr) > \ > for (iter.init = (ptr)->head, iter.next = iter.cur->next; > \ > iter.cur != iter.end > \ > iter.cur = iter.next, iter.next = iter.cur->next) > > With that and some trivial changes *all* multiple evaluation possibilities > are gone. > > (_iter_ in there would go, thats just so I can have both in the same file > for now).
I am thinking whether a macro like: #if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6) #define assert_compatible_types(a, b) _Static_assert( \ __builtin_types_compatible_p(a, __typeof__ (b) ), \ "variable `" #b "` is not compatible to type `" #a "`" ) #else #define assert_compatible_types(a, b) (void)0 #endif used like: #define dlist_iter_foreach(iter, ptr) \ assert_compatible_types(dlist_iter, iter); \ for (iter.init = (ptr)->head; iter.cur != iter.end; \ iter.cur = iter.cur->next) would be useful. If you use the wrong type you get an error like: error: static assertion failed: "variable `iter` is not compatible to type `dlist_iter`" Do people think this is something worthwile for some of the macros in pg? At times the compiler errors that get generated in larger macros can be a bit confusing and something like that would make it easier to see the originating error. I found __builtin_types_compatible while perusing the gcc docs to find whether there is something like __builtin_constant_p for checking the pureness of an expression ;) Andres -- Andres Freund http://www.2ndQuadrant.com/ PostgreSQL Development, 24x7 Support, Training & Services -- Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org) To make changes to your subscription: http://www.postgresql.org/mailpref/pgsql-hackers