Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

P0533R9 constexpr For <cmath> And <cstdlib> #2530

Open
StephanTLavavej opened this issue Feb 8, 2022 · 9 comments
Open

P0533R9 constexpr For <cmath> And <cstdlib> #2530

StephanTLavavej opened this issue Feb 8, 2022 · 9 comments
Labels
compiler Compiler work involved cxx23 C++23 feature

Comments

@StephanTLavavej
Copy link
Member

StephanTLavavej commented Feb 8, 2022

P0533R9 constexpr For <cmath> And <cstdlib>
LWG-3834 Missing constexpr for std::intmax_t math functions in <cinttypes>

Feature-test macro:

#define __cpp_lib_constexpr_cmath 202202L
@StephanTLavavej StephanTLavavej added the cxx23 C++23 feature label Feb 8, 2022
@CaseyCarter
Copy link
Member

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.

@StephanTLavavej StephanTLavavej added the compiler Compiler work involved label Feb 8, 2022
@AlexGuteniev
Copy link
Contributor

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.

@frederick-vs-ja
Copy link
Contributor

frederick-vs-ja commented Feb 13, 2022

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.

Edit: The alternatename trick is unnecessary. I guess we can just sweep UCRT functions in a non-global internal namespace in C++ modes.

@fsb4000
Copy link
Contributor

fsb4000 commented Feb 14, 2022

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 <cmath>
namespace std {
  constexpr int abs(int) {...}
}

// 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

@StephanTLavavej
Copy link
Member Author

I've contacted the compiler team about getting support for this.

@StephanTLavavej
Copy link
Member Author

We should ask the compiler team to consider implementing #3789 at the same time to save work.

@blackninja9939
Copy link
Contributor

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

@frederick-vs-ja
Copy link
Contributor

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.

@frederick-vs-ja
Copy link
Contributor

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.

Ah, it seems that no progress seem was made since then. If MS had allowed us to touch related UCRT headers or reorganize them like <stdatomic.h>, we would probably have implemented the whole library workaround before 2024.
(Also, the alternatename trick does't seem unnecessary. Probably another internal namespace suffices.)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
compiler Compiler work involved cxx23 C++23 feature
Projects
Status: Blocked
Development

No branches or pull requests

6 participants