Michael Haggerty <[email protected]> writes:
> *sigh* of course you're right. I should know better than to "fire off a
> quick fix to the mailing list".
>
> I guess the two proposals that are still in the running for rescuing
> this macro are Jonathan's and Gábor's. I have no strong preference
> either way.
If somebody is writing this outisde a macro as a one-shot thing, the
most natural and readable way I would imagine would be
if (the list is empty)
;
else
for (each item in the list)
work on item
I would think. That "work on item" part may not be a single
expression statement and instead be a compound statement inside a
pair of braces {}. Making a shorter version, i.e.
if (!the list is empty)
for (each item in the list)
work on item
into a macro probably has syntax issues around cascading if/else
chain, e.g.
if (condition caller cares about)
for_each_string_list_item() {
do this thing
}
else
do something else
would expand to
if (condition caller cares about)
if (!the list is empty)
for (each item in the list) {
do this thing
}
else
do something else
which is wrong. But I couldn't think of a way to break the longer
one with the body of the macro in the "else" clause in a similar
way. An overly helpful compiler might say
if (condition caller cares about)
if (the list is empty)
;
else
for (each item in the list) {
do this thing
}
else
do something else
that it wants a pair of {} around the then-clause of the outer if;
if we can find a way to squelch such warnings only with this
construct that comes from the macro, then this solution may be ideal.
If we cannot do that, then
for (item = (list)->items; /* could be NULL */
(list)->items && item < (list)->items + (list)->nr;
item++)
work on item
may be an obvious way to write it without any such syntax worries,
but I am unclear how a "undefined behaviour" contaminate the code
around it. My naive reading of the termination condition of the
above is:
"(list)->items &&" clearly means that (list)->items is not
NULL in what follows it, i.e. (list->items + (list)->nr
cannot be a NULL + 0, so we are not allowed to make demon
fly out of your nose.
but I wonder if this alternative reading is allowed:
(list)->items is not assigned to in this expression and is
used in a subexpression "(list)->items + (list)->nr" here;
for that subexpression not to be "undefined", it cannot be
NULL, so we can optimize out "do this only (list)->items is
not NULL" part.
which takes us back to where we started X-<. So I dunno.
I am hoping that this last one is not allowed and we can use the
"same condition is checked every time we loop" version that hides
the uglyness inside the macro.