为什么我可以在constexpr函数中调用一个非constexpr函数? [英] Why can I call a non-constexpr function inside a constexpr function?

查看:1857
本文介绍了为什么我可以在constexpr函数中调用一个非constexpr函数?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

请考虑以下代码:

  #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 inside f, because f is supposed to be constexpr, but printf 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 cause gcc 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 of printf.

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆