On Mon, 14 Jan 2019 at 10:29, Richard Biener <richard.guent...@gmail.com> wrote: > > _GLIBCXX14_CONSTEXPR bool > > operator()(_Tp* __x, _Tp* __y) const _GLIBCXX_NOTHROW > > { > > +#if __cplusplus >= 201402L > > +#ifdef _GLIBCXX_HAVE_BUILTIN_IS_CONSTANT_EVALUATED > > + if (__builtin_is_constant_evaluated()) > > +#else > > if (__builtin_constant_p (__x > __y)) > > +#endif > > return __x > __y; > > +#endif > > return (__UINTPTR_TYPE__)__x > (__UINTPTR_TYPE__)__y; > > I wonder what the idea behind this is. It smells like trying to avoid > undefined behavior (relational compare of pointers to different objects?) > but then executing that nevertheless when "constant"? > > I think this just doesn't work since the compiler, when evaluating > __x > __y [for constant folding] is exploiting the fact that doing > non-equality compares on pointers into different objects invoke > undefined behavior.
When that happens, the function is ill-formed when constant-evaluated, which is fine. When the comparison is not UB, it should constant-evaluate without problems. > So why is this not just > return (__UINTPTR_TYPE__)__x > (__UINTPTR_TYPE__)__y; > or with the casts elided? Those casts are reinterpret_casts, so the function could never be constant-evaluated. The casts need to be there to avoid UB for the run-time cases.