MSVC C++23:使用 LLVM Libc 实现 constexpr cmath

MSVC C++23:使用 LLVM Libc 实现 constexpr cmath

💡 原文英文,约1000词,阅读约需4分钟。
📝

内容提要

微软在C++23中使标准库数学函数支持编译期求值,并在MSVC 14.52中实验性实现。由于UCRT数学函数精度不足且结果随系统变化,微软改用LLVM libc数学库,以兼顾精度、稳定性、一致性与性能,同时用于编译期和运行时。该功能默认关闭,需启用相关选项,微软希望收集用户反馈。

🔎

延伸解读

为何需要新的数学库

文章指出,UCRT数学函数存在已知精度问题,且其实现随操作系统更新而变化,导致计算结果可能因OS版本或硬件架构不同而不同。在C++23中,编译期求值可能通过模板参数等方式进入ABI,这种不稳定性尤其不可接受。因此微软需要一个新的数学库来满足精度、稳定性、一致性和性能要求。

LLVM libc如何满足需求

微软评估后选择LLVM libc,因其以数学精度为首要目标,追求所有舍入模式下的正确舍入,并得到Gladman等人研究的验证。该库活跃维护、代码可组合,易于适配MSVC。性能测试显示其常能与UCRT媲美,因此微软决定在编译期和运行时都使用它,以提供一致、稳定、精确且高效的结果。

实验性启用的影响与反馈

该功能默认关闭,需同时使用/std:c++23或更高版本和/Zc:cmath选项启用。由于新数学库可能改变现有程序的性能和精度特性,微软将其作为实验性功能发布,以收集用户反馈后再决定默认行为。用户可通过Visual Studio开发者社区报告问题。

对C++26的铺垫

文章提到,为C++23集成LLVM libc的工作为C++26奠定了基础。LLVM libc尚未实现所有在C++26中成为constexpr的函数,但微软已为就绪的函数(如sin、cos、tan、pow)添加支持,并持续关注尚未实现的函数(如lgamma)。

Q&A

MSVC 14.52 中如何启用 constexpr cmath 功能?

需要同时使用 /std:c++23 或更高版本和 /Zc:cmath 编译器选项。该功能默认关闭,以实验性形式提供。

为什么微软要放弃 UCRT 数学函数而改用 LLVM libc?

UCRT 数学函数存在已知的数学不准确性,且结果会随操作系统版本和硬件架构变化,无法满足 C++23 编译期求值对精度、稳定性、一致性和性能的要求。LLVM libc 以数学准确性为首要目标,能提供一致、稳定、准确且高性能的结果。

新的数学库在编译期和运行时都使用吗?

是的,微软将 LLVM libc 同时用于编译期和运行时,以提供一致、稳定、准确且高性能的数学结果。

这个功能目前是默认开启的吗?

不是,该功能最初作为实验性功能发布,默认关闭。微软希望收集用户反馈后再决定默认行为。

LLVM libc 已经支持所有 C++26 的 constexpr 数学函数了吗?

还没有。LLVM libc 尚未实现所有在 C++26 中成为 constexpr 的函数,但微软已经添加了对已就绪函数的支持,例如 sin、cos、tan 和 pow,并正在关注尚未支持的函数如 lgamma。

如何向微软反馈关于这个实验性功能的问题?

可以在 Visual Studio Developer Community 上报告问题或提供反馈。

🏷️

标签

➡️

继续阅读