【发布时间】:2026-01-16 15:10:01
【问题描述】:
gcc 编译以下代码而不发出警告:
#include <cmath>
struct foo {
static constexpr double a = std::cos(3.);
static constexpr double c = std::exp(3.);
static constexpr double d = std::log(3.);
static constexpr double e1 = std::asin(1.);
static constexpr double h = std::sqrt(.1);
static constexpr double p = std::pow(1.3,-0.75);
};
int main()
{
}
上面使用的标准库函数都不是constexpr 函数,我们可以在the draft C++11 standard 和draft C++14 standard 都需要常量表达式 的地方使用它们部分7.1.5 [dcl.constexpr]:
[...]如果它是由构造函数调用初始化的,则该调用应为 常量表达式(5.19)。否则,或者如果 constexpr 说明符是 在引用声明中使用,出现在 它的初始化器应该是一个常量表达式。[...]
即使使用 -std=c++14 -pedantic 或 -std=c++11 -pedantic 也不会生成警告 (see it live)。使用 -fno-builtin 会产生错误 (see it live),这表明这些标准库函数的 builtin 版本被视为在 constexpr
虽然clang 不允许代码带有我尝试过的任何标志组合。
所以这是一个gcc 扩展,将至少一些内置函数视为constexpr 函数,即使标准没有明确要求它们是。我本来希望至少在严格一致性模式下收到警告,这是一个符合标准的扩展吗?
【问题讨论】:
标签: c++ c++11 gcc language-lawyer c++14