格式错误,无需诊断 (NDR):C++14 中的 ConstExpr 函数抛出

2023-12-06

#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),程序格式错误;无需诊断。

它被描述为“格式错误,无需诊断“ 因为抛出表达式不是一个核心常量表达式(5.19/2)。然而,Clang 和 GCC 都编译成功(Ideone).

  • 这段代码是正确的(标准中存在错误)还是不正确(Clang 和 GCC 中都存在错误)?

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

  • 未定义行为和格式错误之间的区别,不需要诊断消息
  • “无需诊断”的理由是什么?
  • 根据标准,C++ 编译器需要如何处理格式错误的程序?

是否有可能一个/这个程序是“格式错误,无需诊断“并且允许编译器成功编译它?


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

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

还是它不正确(Clang 和 GCC 中都存在错误)?

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

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

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

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

如果格式错误的程序确实可以编译,则该标准不会指定此类程序应如何运行。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

格式错误,无需诊断 (NDR):C++14 中的 ConstExpr 函数抛出 的相关文章

随机推荐