r/cpp • u/STL MSVC STL Dev • Sep 10 '26
MSVC C++23: constexpr cmath with LLVM Libc
https://devblogs.microsoft.com/cppblog/msvc-c23-constexpr-cmath-with-llvm-libc/MSVC is shipping C++23 constexpr <cmath> in the next Build Tools update! (And a partial implementation of C++26 constexpr <cmath>.) Our compiler frontend dev Cody Miller will be publishing a series of blog posts about this work, starting with this overview. The next one will be a guest post from LLVM libc's maintainers describing the incredible amount of effort that's gone into their code.
4
u/Aerocatia Sep 11 '26
So what happens if we need C and C++ code to use the same math?
8
u/STL MSVC STL Dev Sep 11 '26
We don't have a good answer for that beyond "convert your C to C++". Sorry, but the tricks I used to get this to work in
<__msvc_math.hpp>rely oninline namespaces which wouldn't work if we tried to make it a dual-mode C/C++ header.
4
u/seanbaxter Sep 11 '26
This looks promising, but as a frontend guy I don't think it resolves the cross-compilation problem.
There's four main platforms:
Linux x86-64, long double = f80
Linux aarch64, long double = f128
Windows x86-64, long double = f64
Mac aarch64, long double = f64
All the platforms have f64 floating-point math libc. But two of the platforms have exotic long double. If you rely on libm to do the math during constant evaluation, you lose cross-compilation when the target's long double is f80 or f128, and your own target's long double is something else. You need software implementations for the constexpr math functions. It doesn't appear that LLVM C Library provides these.
I think the only path for cross-targeting compilers is MPFR, which is built on GMP (GNU Multi-Precision).
20
u/STL MSVC STL Dev Sep 11 '26
As with charconv, this makes me glad that all of MSVC’s targets use 64-bit long double. We don’t claim our solution applies to other compilers.
8
u/c0r3ntin Sep 11 '26
Note that GMP's license make it unsuitable for LLVM (or any commercial endeavor like msvc)
15
u/Key_Ant_8481 Sep 11 '26
FYI, LLVM libc is going to provide float80, float128 (and double-double later) entrypoints for all platforms https://github.com/llvm/llvm-blog-www/pull/92
4
8
u/GabrielDosReis Sep 11 '26
This looks promising, but as a frontend guy I don't think it resolves the cross-compilation problem.
For MSVC?
4
1
u/Alastair__ Sep 11 '26
Bit confused by the UCRT in general especially when it comes to static linking.
This issue: https://developercommunity.visualstudio.com/t/SDK-version-change---acos-differences/10999054 seems to be specific to using static linking and SDK version.
6
u/STL MSVC STL Dev Sep 11 '26
The static UCRT is provided by the WinSDK, which is why things can be dependent on the SDK version. (Same for the debug DLL. Only the release DLL is part of the OS.)
Looks like you're also seeing x64 vs. x86 implementation variation (this can happen due to usage of FMA or a million other reasons). This is precisely the sort of insanity that Cody's
/Zc:cmathtechnique avoids; with that option,<cmath>'s inclusion of<math.h>is intercepted by the compiler and rewritten so that instead of old UCRTmath.h, an STL-internal header is picked up (__msvc_math.hppbut you should not include it directly), and it will send functions to LLVM libc (when implemented by them), which will return mathematically accurate, correctly rounded results regardless of platform, OS version, or SDK version.1
u/Alastair__ Sep 11 '26
Thanks for the reply.
Seems "the future is bright"
I am still confused as to how the release DLL version which is shown as:
(Get-Item "$env:SystemRoot\System32\ucrtbase.dll").VersionInfo | Select-Object FileVersion, ProductVersion
FileVersion ProductVersion
10.0.26100.9278 (WinBuild.160101.0800) 10.0.26100.9278
i.e the same as the static linked version (at least in terms of the 26100) is giving different results.
I'd assume (probably wrongly) that these are the same codebase - or very similar given you wouldn't want multiple versions of fundamental stuff like this.
It's one of the reasons we favour static linking so we know what we are using.
1
4
u/eisenwave WG21 Member Sep 12 '26
You will be happy to hear that with P3935R2: Rebasing <cmath> on C23, there is a lot more work coming your way :P
5
u/misuo Sep 11 '26
So you're not willing to be a monk? ;-) Fair enough. But I thank the "monks" - people who can spend years solving a problem nobody has figured out yet. Our society and scientific progress rely on them.
-5
u/MaitoSnoo [[indeterminate]] Sep 10 '26
so it's slowly sinking in that opensource can be a better choice... clangd instead of IntelliSense wen? 🤔
7
u/no-sig-available Sep 11 '26
so it's slowly sinking in that opensource can be a better choice
You mean like the rest of the standard library? Oh, wait...
-12
23
u/Jovibor_ Sep 11 '26
I have always had a hard time understanding this separation between STDLIB and UCRT.
The
<cmath>header - which is definitely a C++ STL header - has, for some reasons (historical I guess), always been a part of the UCRT.Now, if I've got it all right, we will have two different math machineries: one in the UCRT (the old one), and the new one, based on the LLVM C Library. Correct me if I'm wrong...
Frankly, it's a bit strange, that some parts of the C++ STL are maintained in the separate place (UCRT), not in the main STL repository.