c – 考虑到非常数表达式函数的内建是gcc是常量表达式

c – 考虑到非常数表达式函数的内建是gcc是常量表达式,第1张

概述请参阅更新以获得更好的问题样本.原始代码混合了一些混乱的问题: 这个问题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 ma 请参阅更新以获得更好的问题样本.原始代码混合了一些混乱的问题:

这个问题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("%zd\n",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函数的内置函数可以被认为是一个常量表达式.

如果确实如此:

编译器是否允许这样做?
>如果允许的话,他们是否必须将其记录为符合标准?
>这可以被认为是扩展,如果是这样,似乎这将需要警告,因为C++ draft standard第1.4节实施合规第8段说(强调我的):

A conforming implementation may have extensions (including additional library functions),provIDed they do not alter the behavior of any well-formed program. Implementations are required to diagnose programs that use such extensions that are ill-formed according to this International Standard. Having done so,however,they can compile and execute such programs.

更新

正如凯西指出的那样,在原始问题中有一些事情使它成为一个很差的例子.一个简单的例子是使用std::pow这不是一个constexpr函数:

#include <cmath>#include <cstdio>constexpr double f(){    return std::pow( 2.0,2.0 ) ;}int main(){    constexpr double x = f() ;    printf( "%f\n",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 2013 does seem to allow GCC to treat these functions as constexpr.
So,fixed for 4.7

这是指LWG issue 2013,其原始建议的决议是将以下内容添加到第17.6.5.6节[constexpr.functions](重点是我的未来):

[…]Additionally,an implementation may declare any function to be
constexpr if that function’s deFinition satisfIEs the necessary
constraints[…]

但在C11之后,该决议被撤销,最终决议最终如下:

[…]An implementation shall not declare any standard library function
signature as constexpr except for those where it is explicitly
required.[..]

所以这是目前(在C 14)a explicitly non-conforming extension,据我所知,这是不符合C11,因为它改变了可观察的行为,因此不允许通过as-if规则.

Jonathan Wakely指出了一个libstdc邮件列表讨论:PR libstdc++/49813 revisited: constexpr on functions (and builtins)由于上述问题,上面讨论了重新打开上面提到的错误报告:

I belIEve we should re-open the BUG in light of the actual resolution
of LWG 2013 (adding constexpr is forbIDden).

The FE should not treat builtins as constexpr in strict-conformance
mode.

We should either remove _GliBCXX_CONSTEXPR from <cmath> entirely or make it conditional on __STRICT_ANSI__.

总结

以上是内存溢出为你收集整理的c – 考虑到非常数表达式函数的内建是gcc是常量表达式全部内容,希望文章能够帮你解决c – 考虑到非常数表达式函数的内建是gcc是常量表达式所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/langs/1251260.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-07
下一篇 2022-06-07

发表评论

登录后才能评论

评论列表(0条)

保存