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函数,根据C++11标准草案和C++14标准草案第7.1.5
节 [dcl.constexpr]规定,我们可以在需要常量表达式的地方使用它们:
即使使用[...]如果它通过构造函数调用进行初始化,则该调用应为常量表达式(5.19)。否则,或者如果在引用声明中使用了constexpr说明符,则出现在其初始化器中的每个完整表达式都应为常量表达式.[...]
-std=c++14 -pedantic
或-std=c++11 -pedantic
,也不会产生警告(请参见实时演示)。使用-fno-builtin
会产生错误(请参见实时演示),这表明这些标准库函数的内置版本被视为constexpr。虽然我尝试了多种标志组合,但
clang
不允许该代码。因此,这是一个
gcc
扩展,将至少一些内置函数视为constexpr函数,即使标准并未明确要求。在严格的符合模式下,我至少希望收到警告,这是一个符合性扩展吗?
__
开头的名称都保留给实现,实现定义它们的语义。对于特定于实现的函数的语义,无论它们是否是内部函数,完全可以由实现者自行决定将其定义为constexpr
。 - Ben Voigtgcc
错误报告中提到了内部函数的主题,以及在此处的评论中提到了它,因此即使答案似乎很明显,提到它似乎也是相关的。我同意您关于as-if规则的看法,我应该让它更明显,现在已经更新了。 - Shafik Yaghmour