为什么我可以在constexpr函数中调用一个非constexpr函数? [英] Why can I call a non-constexpr function inside a constexpr function?
问题描述
请考虑以下代码:
#include< stdio.h>
constexpr int f()
{
return printf(a side effect!\\\
);
}
int main()
{
char a [f()];
printf(%zd \\\
,sizeof a);
}
我希望编译器抱怨调用 printf
里面 f
,因为 f
应该是 constexpr
,但 printf
不是。为什么程序编译并打印15 ?
该程序是错误的,不需要诊断 C ++ 11草稿标准部分 7.1.5
constexpr说明符段落 5 :
对于constexpr函数,如果没有函数参数值,函数调用替换将产生一个常量
表达式(5.19),程序是不成形的;无需诊断。
并提供以下示例:
constexpr int f(bool b)
{return b?}抛出0:0; } // OK
constexpr int f(){return f(true); } //形成错误,无需诊断
和 code>段落 2 说:
条件表达式是一个核心常量表达式,除非
涉及以下之一作为潜在求值的子表达式
[...]
,包括: p>
- 调用
文字类或constexpr函数的constexpr构造函数以外的函数[注意:过载解析
(13.3)应用于通常的情况];
在这种情况下我们可能更喜欢诊断,是一个监督,我有一个类似的情况下的错误报告 gcc
不会产生错误,但我们可能会喜欢它:编译器允许在它认为未定义行为的余地常数表达式?。
更新
使用 -fno-builtin
标志会导致 gcc
产生以下错误:
错误:调用非constexpr函数'int printf(const char *,...)'
return printf(a side effect!\\\
);
^
因此 gcc
考虑这个形式不正确它只是忽略它,当它使用内置版本 printf
。
虽然使用 -pedantic
有些不一致,但会产生以下警告:
警告:ISO C ++禁止可变长度数组'a'[-Wvla]
char a [f()];
^
注意,使用 f $ c>初始化一个 constexpr 变量:
constexpr int x = f
会产生错误:
错误:'printf((const char *)a side effect!\012))'不是常量表达式
$请注意,在更一般的情况下,编译器不允许标记库函数作为 constexpr 未经标准明确允许。
Consider the following code:
#include <stdio.h> constexpr int f() { return printf("a side effect!\n"); } int main() { char a[f()]; printf("%zd\n", sizeof a); }
I would have expected the compiler to complain about the call to
printf
insidef
, becausef
is supposed to beconstexpr
, butprintf
is not. Why does the program compile and print 15?解决方案The program is ill-formed and requires no diagnostic according to the C++11 draft standard section
7.1.5
The constexpr specifier paragraph 5 which says:For a constexpr function, if no function argument values exist such that the function invocation substitution would produce a constant expression (5.19), the program is ill-formed; no diagnostic required.
and provides the following example:
constexpr int f(bool b) { return b ? throw 0 : 0; } // OK constexpr int f() { return f(true); } // ill-formed, no diagnostic required
and section
5.19
paragraph 2 says:A conditional-expression is a core constant expression unless it involves one of the following as a potentially evaluated subexpression [...]
and includes:
— an invocation of a function other than a constexpr constructor for a literal class or a constexpr function [ Note: Overload resolution (13.3) is applied as usual —end note ];
We would probably prefer a diagnostic in this case, it could just be an oversight, I have a bug report for a similar situation where
gcc
does not produce an error but we would probably like it to: Is the compiler allowed leeway in what it considers undefined behavior in a constant expression?.Update
Using the
-fno-builtin
flag will causegcc
to generate the following error:error: call to non-constexpr function 'int printf(const char*, ...)' return printf("a side effect!\n"); ^
So
gcc
does consider this ill-formed it is just ignores it when it is using the builtin version ofprintf
.Although somewhat inconsistently using the
-pedantic
produces the following warning:warning: ISO C++ forbids variable length array 'a' [-Wvla] char a[f()]; ^
Note that using
f()
to initialized a constexpr variable:constexpr int x = f() ;
does generate an error:
error: 'printf(((const char*)"a side effect!\012"))' is not a constant expression
Note that additionally in the more general case a compiler is not allowed mark standard library functions as constexpr unless explicitly allowed by the standard.
这篇关于为什么我可以在constexpr函数中调用一个非constexpr函数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!