Is gcc considering builtins of non-constant expression functions to be constant expressions

北慕城南 提交于 2019-11-27 21:29:54
Shafik Yaghmour

Yes, gcc is considering some builtin functions as constexpr even if the standard does not explicitly mark them as such. We can find the discussion that pertains specifically to the math function found in cmath in the gcc bug report [C++0x] sinh vs asinh vs constexpr which says:

LWG 2013 does seem to allow GCC to treat these functions as constexpr. So, fixed for 4.7

which is referring to LWG issue 2013 whose original proposed resolution was to add the following to section 17.6.5.6 [constexpr.functions] (emphasis mine going forward):

[...]Additionally, an implementation may declare any function to be constexpr if that function's definition satisfies the necessary constraints[...]

but after C++11 the resolution was reversed and the final resolution ended up as:

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

So this is currently(in C++14) a explicitly non-conforming extension and as far as I can tell this was non-conforming in C++11 since it alters observable behavior and therefore would not be allowed via the as-if rule.

Jonathan Wakely points out a libstdc++ mailing list discussion: PR libstdc++/49813 revisited: constexpr on functions (and builtins) where reopening the bug report mentioned above was discussed due to the issues laid out above:

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__.

GCC does not consider f() to be a constant expression. Look at the diagnostics for the first sample program you linked:

main.cpp: In function 'int main()':
main.cpp:10:19: warning: ISO C++ forbids variable length array 'a' [-Wvla]
         char a[f()];
                   ^

The compiler doesn't think f() is a constant expression, the program is in fact using GCC's extension that allows variable length arrays - arrays with non-constant size.

If you change the program to force f() into a constant expression:

int main() {
    constexpr int size = f();
    char a[size];
    printf("%zd\n", sizeof a);
}

GCC does report an error:

main.cpp: In function 'int main()':
main.cpp:10:32:   in constexpr expansion of 'f()'
main.cpp:5:41: error: 'printf(((const char*)"a side effect!\012"))' is not a constant expression
         return printf("a side effect!\n");
                                         ^
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!