On Sat, Oct 15, 2022 at 10:07:46AM +0200, Martin Uecker wrote: > But why? Do we really want to encourage people to > write such code?
Of course these ++ cases inside of expressions are just obfuscation. But the point is to support using predicates that can be inlined and simplified into something really simple the optimizers can understand. The paper shows as useful e.g. being able to assert something is finite: [[assume (std::isfinite (x)]]; and with the recent changes on the GCC side it is now or shortly will be possible to take advantage of such predicates. It is true that [[assume (__builtin_isfinite (x)]]; could work if we check TREE_SIDE_EFFECTS on the GCC side because it is a const function, but that is a GNU extension, so the standard can't count with that. std::isfinite isn't even marked const in libstdc++ and one can figure that out during IPA propagation only. There are many similar predicates, or user could have some that are useful to his program. And either in the end it wouldn't have side-effects but the compiler doesn't know, or would but those side-effects would be unimportant to the optimizations the compiler can derive from those. As the spec defines it well what happens with the side-effects and it is an attribute, not a function and the languages have non-evaluated contexts in other places, I don't see where a user confusion could come. We don't warn for sizeof (i++) and similar either. __builtin_assume (i++) is a bad choice because it looks like a function call (after all, the compilers have many similar builtins) and its argument looks like normal argument to the function, so it is certainly unexpected that the side-effects aren't evaluated. Jakub