Open StephanTLavavej opened 2 years ago
We need to investigate this sooner rather than later to determine exactly how we're going to make UCRT functions constexpr
. I suspect we'll have to teach the compiler(s) to recognize e.g. ::ldexp
and std::ldexp
, at least when they appear in constant expressions, and constant-fold them. This is going to involve a lot of joint work and communication with our compiler teams.
I think it is implementable without compiler support. You have constexpr bit_cast
, you know the representation of floats, you do the math.
Compiler support looks better though. Be sure to have it in clang-cl either.
I don't think compiler support is essentially needed (but may be nice to have). We can ask UCRT not to declare these functions, but to provide some equivalent functions with different names (e.g. __cstd_fabs
, which may be suitable to be called at runtime) in C++23 mode. The definitions of existing UCRT functions can be unchanged.
Perhaps we can provide "some equivalent functions with different names" in MSVC STL only, by [[__gnu__::__alias__("...")]]
(for clang) or #pragma comment(linker, "/alternatename:...")
(for MSVC, see this).
For example, we might be able to change our ldexp
to have "C++" language linkage in C++23 mode, and hence it will be mangled and won't conflict to the ldexp
in UCRT (which has "C" language linkage). And it may call __cstd_ldexp
at runtime, where __cstd_ldexp
is an alias for the ldexp
in UCRT.
a few initial thoughts from LLVM discord: https://discord.com/channels/636084430946959380/636732781086638081/942850475752062989
@ldionne wrote:
Oh! Of course.
// inside <math.h> int abs(int);
// inside
// user code: using namespace std; abs(1); // which one is meant?
>Okay.. yeah this is messed up
>
>Geez I don't know how to solve that problem, actually
>
>Well the only way would be for the C standard library version to be constexpr
>
>Either by means of them defining it as such, or the compiler doing some extra nasty magic when it sees these names
>
>However, asking the C library folks to implement something based on something like std::is_constant_evaluated() is not a happy story
I've contacted the compiler team about getting support for this.
We should ask the compiler team to consider implementing #3789 at the same time to save work.
The attribute [[msvc::constexpr]] allows "extended constexpr" in C++20 such as calling placement new from within a constexpr function for std::construct_at, could that attribute be extended to allow using these blessed functions in a constant expression?
Seems like the least painful approach in terms of existing blessed constexpr and without needing to reimplement every function manually again
Seems like the least painful approach in terms of existing blessed constexpr and without needing to reimplement every function manually again
I think the crux is the UCRT headers (mainly <math.h>
in the case of this issue) - they seem somehow "freezed", so it's unclear whether we can even add attributes to declarations in them. As a result, compiler frontends seemingly need work around this when such a function calls is encountered in constant evaluation.
P0533R9
constexpr
For<cmath>
And<cstdlib>
LWG-3834 Missingconstexpr
forstd::intmax_t
math functions in<cinttypes>
Feature-test macro: