[PATCH] libstdc++: Adjust generate_canonical (P0952, LWG2524) [PR119739]

Nathan Myers ncm@cantrip.org
Tue Aug 12 13:18:12 GMT 2025


Thank you, this was all very helpful. v8 posted.
But...

>> +      const int __k = [](_RealT __rd, _RealT __R) consteval
>>
> I will use if constexpr for __R being a power of two, and use __builtin_log
> in that case. You may need to add #pragma GCC diagnostic ignored
> "-Wc++17-extensions"
> sections around it to avoid issues.

Is this to optimize build time? If it produces the same answer, it
seems to only add complexity, otherwise, when the lambda must be
there anyway; and in common cases (u32 -> float, u64 -> double)
it runs only one iteration.

>> +       {
>> +         unsigned __k = 1;
>> +         _RealT __Ri = __R;
>> +         while (__Ri < __rd)
>> +           { __Ri *= __R, ++__k; }
>> +         return __k;
>> +       } (__rd, __R);
>>
> +      constexpr static _RealT __Rk = __pow(__R, __k);>> +      constexpr static  _RealT __x = [](_RealT __Rk, _RealT __rd)
>> consteval
>> +       { return std::floor(__Rk/__rd); }(__Rk, __rd);
>>
> I think this will not compile in clang, even built-ins are not constexpr
> there.

In v8, I guarded it with #ifndef __clang__.
But maybe some finer-grain predicate would be better?
An alternative would be to keep the __pow() lambda for that case, and
__floor = [](auto x) { return (_RealT)(uint64_t)(x - 0.5); }
(with maybe a more complicated substitute for uint64_t).



More information about the Libstdc++ mailing list