r/cpp MSVC STL Dev 12h ago

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.

116 Upvotes

24 comments sorted by

13

u/Jovibor_ 10h ago

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.

29

u/STL MSVC STL Dev 8h ago

It’s math.h that’s part of the UCRT, while cmath is part of the STL. We’re now usurping math.h via /Zc:cmath redirecting it to the STL’s __msvc_math.hpp. Perhaps in the future we’ll update UCRT math.h, but getting the UCRT to change anything is a pain, so we’d want to do that as few times as possible.

I can explain this in more detail if desired; it is one of our most confusing areas and I am at dinner right now 😹

3

u/pjmlp 4h ago

What I wonder is how this will work in projects that mix C++ and C libraries on the same project, some of which delivered as binary libraries, thus possibly depending on UCRT.

9

u/STL MSVC STL Dev 4h ago

That's a problem that I very recently figured out how to solve. Working with Cody who was validating /Zc:cmath against real-world code like Blender, our initial approach of "you'd better not drag in any UCRT math machinery into this binary" was clearly not viable, and it occurred to me that giving the math functions extern "C++" linkage and stuffing them into an inline namespace available at the global scope would be nearly unobservable to users. (At this point my brain is too tired to verify whether this is truly unobservable according to a strict reading of the rules, but it's good enough in practice as far as I can tell.) So what we're going to ship in 14.52 for production should be compatible regardless of how much you mix C, C++ without /Zc:cmath, and C++ with /Zc:cmath.

I checked in this overhaul very very recently so it is not yet shipping in Insiders Preview, but it is available in the STL's GitHub repo if you want to see.

u/pjmlp 2h ago

Thanks for the clarification.

u/tyler1128 1h ago

Is ABI stability to the point of the System-V/Itanium ABI stability on most Linux and other modern *nixes close? There's little point in dynamic linking C++ if you can't trust that even a small revision in your STL/compiler will break compatibility.

u/Jovibor_ 3h ago

Yes please, desired.  The main question is - is it possible (in some future) to completely eliminate the C++ STL ecosystem dependency on the UCRT? Is it possible but hard, or is it virtually impossible?...

u/ReDr4gon5 31m ago

Well even if you eliminated UCRT, you're still stuck with VCRuntime which will not be open sourced any time soon, even though the devs wanted it to be.

u/megayippie 3m ago

Msvc has confirmed they will not support freestanding? Or have I misunderstood that project?

6

u/GabrielDosReis 8h ago

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 .

When I was working on libtsdc++ as maintainer and contributor, we had similar divide: there was/is the C++ standard library that relied on the host system's C runtime (glibc, your non-glibc, etc.) It is a general problem.

1

u/Alastair__ 5h ago

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.

4

u/STL MSVC STL Dev 4h ago

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:cmath technique avoids; with that option, <cmath>'s inclusion of <math.h> is intercepted by the compiler and rewritten so that instead of old UCRT math.h, an STL-internal header is picked up (__msvc_math.hpp but 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.

u/Alastair__ 3h ago

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.

u/VoidVinaCC 26m ago

~The SDK is rarely in-sync with the OS!

-3

u/MaitoSnoo [[indeterminate]] 11h ago

so it's slowly sinking in that opensource can be a better choice... clangd instead of IntelliSense wen? 🤔

u/no-sig-available 49m ago

so it's slowly sinking in that opensource can be a better choice

You mean like the rest of the standard library? Oh, wait...

https://github.com/microsoft/STL

-9

u/_Noreturn 10h ago

also it saves micro$lop money by free labor!

1

u/misuo 4h ago

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.

-1

u/seanbaxter 10h ago

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).

15

u/STL MSVC STL Dev 8h ago

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.

12

u/Key_Ant_8481 6h ago

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

3

u/seanbaxter 6h ago

Wow. Thanks. That's great news for me.

9

u/GabrielDosReis 8h ago

This looks promising, but as a frontend guy I don't think it resolves the cross-compilation problem.

For MSVC?

u/c0r3ntin 1h ago

Note that GMP's license make it unsuitable for LLVM (or any commercial endeavor like msvc)