自 C++20 以来,某些 C++ 标准库 constexpr 函数是否隐式允许为 consteval?

F.v*_*.S. 5 c++ language-implementation language-lawyer c++20

从C++20开始,有一些立即函数,在很多情况下无法获取其地址(P1073R3);大多数标准库函数都是不可寻址的(P0551R3)。

另外,有一些constexpr标准函数总是返回相同的常量值(例如标准std::numeric_limits专业化的静态成员函数,std::barrier<F>::max),并且它们都不是可寻址的。

实现可以将这些函数一致地更改为 吗consteval

我打算对标准库实现进行这样的更改,并在 MSVC STL 的存储库中进行了讨论,但到目前为止尚未收到任何答复。我还想知道这样的更改是否是一种改进,因为它可能会减少符号表的大小。

Jan*_*tke 4

\n

实现可以将这些函数一致地更改为 吗consteval

\n
\n

这取决于各个函数。\n如果有任何参数,那么答案是否定的:

\n
consteval int f(int i) { return i; }\n\nconstexpr int g(int i) {\n    // error: call to consteval function \'f(i)\' is not a constant expression\n    return f(i) + 1;\n}\n
Run Code Online (Sandbox Code Playgroud)\n

发生这种情况是因为consteval函数只能使用编译时参数调用(这过于简化,有点复杂),并且函数constexpr可以具有仅在运行时存在的参数。\n另请参阅P1938R3:\xc2\ xa73.1 constexpr 和 consteval 之间的交互

\n

话虽这么说,可以创建不带参数且无法显式寻址的consteval函数,因为 a和不带参数的函数调用之间没有明显的区别。这将是“假设规则”的经典案例。\n另请参阅:“假设”规则到底是什么?constevalconstexprconsteval

\n

但是,追溯执行此操作会破坏 ABI。如果现有应用程序调用 ,std::numeric_limits<float>::max()则此调用将产生链接器错误,因为consteval函数不会发送到库中。\n因此,实现者可能会犹豫是否要修改这样的现有函数。\n当然,这指的是::max()尚未内联的调试版本。\n另请参阅:P2028:什么是 ABI,以及 WG21\n应该对此做什么?

\n