c – 考虑到非常数表达式函数的内建是gcc是常量表达式
请参阅更新以获得更好的问题样本.原始代码混合了一些混乱的问题:
这个问题Why can I call a non-constexpr function inside a constexpr function?提出了以下代码 #include <stdio.h> constexpr int f() { return printf("a side effect!n"); } int main() { char a[f()]; printf("%zdn",sizeof a); } 我正在回答的是不正确的,但是gcc 4.8.2允许它(see it live). 但是,如果我们使用-fno-builtin标志,gcc会生成错误(see it live): error: call to non-constexpr function 'int printf(const char*,...)' return printf("a side effect!n"); ^ 所以看来gcc正在考虑它的内置版本的printf作为一个常数表达式. gcc documents builtins here但是没有记录这种情况,其中一个非constexpr函数的内置函数可以被认为是一个常量表达式. 如果确实如此: 编译器是否允许这样做?
更新 正如凯西指出的那样,在原始问题中有一些事情使它成为一个很差的例子.一个简单的例子是使用std::pow这不是一个constexpr函数: #include <cmath> #include <cstdio> constexpr double f() { return std::pow( 2.0,2.0 ) ; } int main() { constexpr double x = f() ; printf( "%fn",x ) ; } 编译和编译没有任何警告或错误(see it live),但添加-fno-builtin使其生成错误(see it live).注意:why math functions are not constexpr in C++11: error: call to non-constexpr function 'double pow(double,double)' return std::pow( 2.0,2.0 ) ; ^ 解决方法
是的,gcc正在考虑将一些
builtin functions作为constexpr,即使标准没有明确标记它们.我们可以在gcc bug报告
[C++0x] sinh vs asinh vs constexpr中找到与cmath中发现的数学函数有关的讨论:
这是指LWG issue 2013,其原始建议的决议是将以下内容添加到第17.6.5.6节[constexpr.functions](重点是我的未来):
但在C11之后,该决议被撤销,最终决议最终如下:
所以这是目前(在C 14)a explicitly non-conforming extension,据我所知,这是不符合C11,因为它改变了可观察的行为,因此不允许通过as-if规则. Jonathan Wakely指出了一个libstdc邮件列表讨论:PR libstdc++/49813 revisited: constexpr on functions (and builtins)由于上述问题,上面讨论了重新打开上面提到的错误报告:
(编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |