生成错误,无需诊断(NDR):ConstExpr函数在C ++中抛出14

时间:2017-01-31 15:22:00

标签: c++ c++14 constexpr throw

#include <iostream>
using namespace std;

constexpr int f(bool b){ return b ? throw 0 : 0; } // OK 

constexpr int f() { return f(true); } // Ill-Formed, No Diagnostic Required

int main(){

    try{
        f();
    }catch( int x ){
        cout << "x = " << x << endl;
    }

    return 0;
}

此代码是C ++ 14标准(ISO / IEC 14882:2014),第7.1.5节,第5段中的示例:

  

对于非模板,非默认constexpr函数或非模板,非默认,非继承constexpr构造函数,如果不存在参数值,则函数或构造函数的调用可以是已计算的子表达式一个核心常数表达式(5.19),该程序是不正确的;无需诊断。

它描述为&#34; 格式错误,无需诊断&#34;因为一个throw-expression 不是核心常量表达式(5.19 / 2)。但是,Clang和GCC都成功编译了它(Ideone)。

  • 此代码是否正确(标准中有错误)或是否错误(并且Clang和GCC都有错误)?

我还发现了关于标准措辞的这些有趣的讨论:

这个程序是否可能&#34; 格式错误,无需诊断&#34;并且允许编译器成功编译它?

1 个答案:

答案 0 :(得分:4)

  

此代码是否正确(标准中有错误)

标准是决定程序是否“正确”即格式良好的标准。该标准明确指出该计划格式不正确。

  

或是不正确(并且Clang和GCC都有错误)?

该程序格式错误(不正确)。 clang和gcc都符合其观察到的行为标准。

  

是否有可能a / this程序“格式错误,无需诊断”并且编译器可以成功编译它?

是。该标准不要求格式错误的程序必须无法编译。如果程序违反规则,它仅要求实现发出至少一个诊断消息。某些规则不可诊断,如果违反此类规则则不需要诊断。

事实上,该规则被认为是“不可诊断的”,因为编译器很难证明(通常)该规则被违反。通常,“无需诊断”规则违规成功编译。

如果一个格式错误的程序编译,标准没有说明这样的程序应该如何表现。