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()
{
}
Run Code Online (Sandbox Code Playgroud)
的上面使用的标准库函数都不是constexpr功能,我们允许使用它们,其中一个常量表达式从两个需要草案C++ 11标准和草案C++ 14标准部7.1.5
[dcl.constexpr] :
[...]如果它是由构造函数调用初始化的,那么该调用应该是一个常量表达式(5.19).否则,或者如果在引用声明中使用constexpr说明符,则其初始值设定项中出现的每个完整表达式都应为常量表达式.[...]
即使使用-std=c++14 -pedantic
或-std=c++11 -pedantic
没有生成警告(请参见实时).使用-fno-builtin
产生错误(参见实时),表明这些标准库函数的内置版本被视为constexpr
虽然 …
请参阅更新以获得更好的问题示例.原始代码有各种各样的问题,使图片混乱:
这个问题为什么我可以在constexpr函数中调用非constexpr函数?提出了以下代码
#include <stdio.h>
constexpr int f()
{
return printf("a side effect!\n");
}
int main()
{
char a[f()];
printf("%zd\n", sizeof a);
}
Run Code Online (Sandbox Code Playgroud)
我回答的是格式不正确但gcc 4.8.2
允许它(现场观看).
但是,如果我们使用该-fno-builtin
标志gcc
生成错误(请参见它):
error: call to non-constexpr function 'int printf(const char*, ...)'
return printf("a side effect!\n");
^
Run Code Online (Sandbox Code Playgroud)
所以它seems
是gcc
正在考虑的内置版本printf
是一个常量表达式.gcc
这里构建的文档但不记录这种情况,其中非constexpr函数的内置可以被认为是常量表达式.
如果确实如此:
1.4
实现合规性第8段说(强调我的):符合条件的实现可能具有扩展(包括其他库函数),前提是它们不会改变任何格式良好的程序的行为.需要实现来诊断使用根据本国际标准格式不正确的扩展的程序.但是,这样做之后,他们就可以编译和执行这样的程序. …