Because many of the cmath functions are constexpr, even in conformance mode of the compiler, this can lead to ODR issues. It is detectable in C++20 and gives incorrect results. #include <cmath> template<auto F> consteval auto foo( ) { if constexpr (requires { []<int>() {}.template operator()<(F(), void(), 0)>(); }) { return 0; } else { return 1; } } auto a = foo<[]{ return std::sqrt( 4.0 ); }>( ); https://gcc.godbolt.org/z/M6zGTbTfM gcc returns 0, clang/libstdc++ and MSVC return 1. I believe that in conformance -std=c++20 -pedantic mode that gcc should not mark these methods as constexpr
> this can lead to ODR issues I don't think it can the C++ standard allows a compiler to have an extended const expressions IIRC.
The constexpr value returned is different depending on the compiler. If one uses clang and gcc this leads to an ODR issue as void bar( ) { if constexpr( foo<[]{ return std::sqrt( 4.0 ); }>( ) ) { doA( ); } else { doB( ); } }
Also http://eel.is/c++draft/library#constexpr.functions-1 An issue is that it's high level observable and not just an optimization
(In reply to Darrell Wright from comment #3) > Also http://eel.is/c++draft/library#constexpr.functions-1 > > An issue is that it's high level observable and not just an optimization http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2013
(In reply to Andrew Pinski from comment #4) > (In reply to Darrell Wright from comment #3) > > Also http://eel.is/c++draft/library#constexpr.functions-1 > > > > An issue is that it's high level observable and not just an optimization > > http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2013 So it looks GCC decided at the time when the defect report was filed to the C++ language working group, GCC changed to allow the constexpr and then the library working group changed how to explicitly reject these instead.
Right, mostly it can fall under as-if(if it wasn't explicitly disallowed) but because it's observable it can lead to some interesting behaviour differences when libstdc++ is compiled with gcc and clang.
C++23 is making these constexpr anyway so I'm not very inclined to change this now.
And we already have a bug report about the presence of constexpr being non-conforming. IIRC the conclusion has been "yes, but it's more useful to support this than to strictly conform".
See pr 49813. Jakub suggests we should remove 'constexpr' for strict modes at least.
(In reply to Darrell Wright from comment #6) > Right, mostly it can fall under as-if(if it wasn't explicitly disallowed) Adding constexpr *is* explicitly disallowed though.
(In reply to Jonathan Wakely from comment #7) > C++23 is making these constexpr anyway so I'm not very inclined to change > this now. That is good to hear, I thought I had read/heard that there was a lot of roadblocks on that and the behaviour of things like rounding modes.
(In reply to Darrell Wright from comment #2) > The constexpr value returned is different depending on the compiler. If one > uses clang and gcc this leads to an ODR issue as > > void bar( ) { > if constexpr( foo<[]{ return std::sqrt( 4.0 ); }>( ) ) { > doA( ); > } else { > doB( ); > } > } This is EXTREMELY contrived. You've basically set up a program where you detect is std::sqrt is constexpr, and then said you get different results depending whether std::sq
(In reply to Jonathan Wakely from comment #12) > This is EXTREMELY contrived. You've basically set up a program where you > detect is std::sqrt is constexpr, and then said you get different results > depending whether std::sq ... rt is constexpr. Well, yeah. Don't do that then. Nobody forces your code to check whether std::sqrt is constexpr, so just don't. And if your code really chooses between invoking feed_cat() and launch_missiles() based on that condition, you're screwed in C++23 anyway. So just don't do that.
*** Bug 115171 has been marked as a duplicate of this bug. ***