Hi, On 2019-07-31 19:40:09 -0400, Tom Lane wrote: > Andres Freund <and...@anarazel.de> writes: > > Unfortunately foreach(ListCell *lc, ...) doesn't work with the current > > definition. Which I think isn't great, because the large scopes for loop > > iteration variables imo makes the code harder to reason about. > > Yeah, I tried to make that possible when I redid those macros, but > couldn't find a way :-(. Even granting that we're willing to have > a different macro for this use-case, it doesn't seem easy, because > you can only put one <declaration> into the first element of a > for (;;).
I remember hitting that at one point and annoyed/confused as there that restriction came from. Probably some grammar difficulties. But still, odd. > That makes the other idea (of a foreach-ish macro declaring the > listcell value variable) problematic, too :-(. Hm. One way partially around that would be using an anonymous struct inside the for(). Something like #define foreach_node(membertype, name, lst) \ for (struct {membertype *node; ListCell *lc; const List *l; int i;} name = {...}; \ ...) which then would allow code like foreach_node(OpExpr, cur, list) { do_something_with_node(cur.node); foreach_delete_current(cur); } That's quite similar to your: > One idea is that we could do something like > > foreach_variant(identifier, list_value) > { > type *v = (type *) lfirst_variant(identifier); > ... > } > > where the "identifier" isn't actually a variable name but just something > we use to construct the ForEachState variable's name. (The only reason > we need it is to avoid confusion in cases with nested foreach's.) The > lfirst_variant macro would fetch the correct value just by looking > at the ForEachState, so there's no separate ListCell* variable at all. but would still allow to avoid the variable. Greetings, Andres Freund