> On Thu, May 9, 2024 at 1:47 AM Jose E. Marchesi > <jose.marchesi@xxxxxxxxxx> wrote: >> +/* A `break' executed in the head of a `for' loop statement is bound >> + to the current loop in clang, but it is bound to the enclosing loop >> + in GCC. Note both compilers optimize the outer loop out with -O1 >> + and higher. This macro shall be used to annotate any loop that >> + uses cond_break within its header. */ >> +#ifdef __clang__ >> +#define __compat_break >> +#else >> +#define __compat_break for (int __control = 1; __control; --__control) >> +#endif > .. >> + __compat_break >> for (i = zero; i < cnt; cond_break, i++) { >> struct elem __arena *n = bpf_alloc(sizeof(*n)); > > This is too ugly. It ruins the readability of the code. > Let's introduce can_loop macro similar to cond_break > that returns 0 or 1 instead of break/continue and use it as: > > for (i = zero; i < cnt && can_loop; i++) { > > pw-bot: cr I went with the ugliness because I was trying to avoid rewriting the loops in the tests, assuming the tests were actually testing using cond_break in these particular locations would result in a particular number of iterations. The loops for (i = zero; i < cnt; cond_break, i++) BODY and for (i = zero; i < cnt && can_loop; i++) BODY are not equivalent if can_loop implements the same logic than cond_break. The may_goto instructions are somehow patched at run-time, and in a predictable way since the tests are checking for explicit iteration counts, right?