On 25/08/22 14:14, Yury Norov wrote: > On Thu, Aug 25, 2022 at 07:12:05PM +0100, Valentin Schneider wrote: >> +#define for_each_cpu_andnot(cpu, mask1, mask2) \ >> + for ((cpu) = -1; \ >> + (cpu) = cpumask_next_andnot((cpu), (mask1), (mask2)), \ >> + (cpu) < nr_cpu_ids;) > > The standard doesn't guarantee the order of execution of last 2 lines, > so you might end up with unreliable code. Can you do it in a more > conventional style: > #define for_each_cpu_andnot(cpu, mask1, mask2) \ > for ((cpu) = cpumask_next_andnot(-1, (mask1), (mask2)); \ > (cpu) < nr_cpu_ids; \ > (cpu) = cpumask_next_andnot((cpu), (mask1), (mask2))) > IIUC the order of execution *is* guaranteed as this is a comma operator, not argument passing: 6.5.17 Comma operator The left operand of a comma operator is evaluated as a void expression; there is a sequence point after its evaluation. Then the right operand is evaluated; the result has its type and value. for_each_cpu{_and}() uses the same pattern (which I simply copied here). Still, I'd be up for making this a bit more readable. I did a bit of digging to figure out how we ended up with that pattern, and found 7baac8b91f98 ("cpumask: make for_each_cpu_mask a bit smaller") so this appears to have been done to save up on generated instructions. *if* it is actually OK standard-wise, I'd vote to leave it as-is. >> + >> /** >> * cpumask_any_but - return a "random" in a cpumask, but not this one. >> * @mask: the cpumask to search >> -- >> 2.31.1