gcc 如何在 constexpr 上下文中编译 C 函数?

Dre*_*ann 6 c++ gcc clang visual-c++ constexpr

鉴于C++ 标准库(当前)不提供 cmath 函数的 constexpr 版本,请考虑下面的程序。

#include <cmath>
#include <cstring>

int main()
{
    constexpr auto a = std::pow(2, 10);
    constexpr auto b = std::strlen("ABC");
}
Run Code Online (Sandbox Code Playgroud)

正如预期的那样,MSVC++ 和 clang++ 无法编译它,因为constexpr变量是从未声明的函数初始化的constexpr

然而,g++ 编译了这个。g++的版本似乎并不重要。

(在编译器资源管理器中查看全部)

g++ 是如何实现这一点的呢?这是正确的(允许的)编译器行为吗?

Art*_*yer 8

LWG 2013的决议是不允许实现将非constexpr函数声明为constexpr,因此 gcc 允许在编译时评估这些函数是不符合要求的。

也就是说,GCC 实际上并未将所需的函数标记为constexpr. 相反,它所做的就是在早期用__builtin_powand替换这些调用__builtin_strlen,它可以在编译时计算(这些std::版本调用 libc 版本,而 libc 版本不能)。这是一个编译器扩展。

如果您使用 进行编译-fno-builtin,它也无法同时编译std::powstd::strlen,但是您可以通过显式写出__builtin_pow(2, 10)和来使 clang 和 GCC 都编译它__builtin_strlen("ABC")


Dee*_*eev 6

如前所述,C++ 标准库当前不支持constexprcmath 函数的计算。然而,这并不能阻止个别实现具有非标准代码。GCC 有一个允许constexpr评估的不合格扩展。