On Mon, Nov 20, 2023 at 07:44:18AM +0000, Richard Biener wrote: > > In https://sourceware.org/pipermail/libc-alpha/2023-November/152819.html > > Florian Weimer raised concern that the type-generic stdbit.h macros > > currently being considered suffer from similar problem as old tgmath.h > > implementation, in particular that the macros expand during preprocessing > > their arguments multiple times and if one nests these stdbit.h type-generic > > macros several times, that can result in extremely large preprocessed source > > and long compile times, even when the argument is only actually evaluated > > once at runtime for side-effects. > > > > As I'd strongly prefer not to add new builtins for all the 14 stdbit.h > > type-generic macros, I think it is better to build the macros from > > smaller building blocks. > > > > The following patch adds the first one. > > While one can say implement e.g. stdc_leading_zeros(value) macro > > as ((unsigned int) __builtin_clzg (value, __builtin_popcountg ((__typeof > > (value)) ~(__typeof (value)) 0))) > > that expands the argument 3 times, and even if it just used > > ((unsigned int) __builtin_clzg (value, __builtin_popcountg ((__typeof > > (value)) -1))) > > relying on 2-s complement, that is still twice. > > > > I'd prefer not to add optional 3rd argument to these, but given that the > > second argument if specified right now has to have signed int type, > > the following patch adds an exception that it allows 0ULL as a magic > > value for the argument to mean fill in the precision of the first argument. > > Ugh. First of all I don't like that the exception is applied during > folding. As for the problem of multi evaluation can't consumers use > stmt expressions for this, say > > {( auto __tem = value; __builtin_xyz (__tem, __typeof (__tem)); ... )} > > ? Thus use 'auto' to avoid spelling 'value' multiple times?
Unfortunately not. See https://sourceware.org/pipermail/libc-alpha/2023-November/152757.html where Joseph said that ({ ... }) can't be used in the implementation, as ({ ... }) is not allowed outside of functions. And I believe e.g. size_t a = sizeof (stdc_leading_zeros (0ULL)); at file scope is valid C23 (we disallow ({ ... }) outside of functions even for C++ BTW). The reason I've changed fold_builtin_bit_query and fold_const_call_sss/fold_const_call_1 is that while the check_builtin_function_arguments change was apparently sufficient for C which when check_builtin_function_arguments changes the args[1] argument will just use whatever it changed to to construct the call, in C++ we first create the call and only then call check_builtin_function_arguments. But I can try to change it... Jakub