Ill-Formed, No Diagnostic Required (NDR): ConstExp

2019-02-25 20:54发布

#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;
}

This code is an example from the C++14 Standard (ISO/IEC 14882:2014), Section 7.1.5, Paragraph 5:

For a non-template, non-defaulted constexpr function or a non-template, non-defaulted, non-inheriting constexpr constructor, if no argument values exist such that an invocation of the function or constructor could be an evaluated subexpression of a core constant expression (5.19), the program is ill-formed; no diagnostic required.

It is described as "ill-formed, no diagnostic required" because a throw-expression is not a core constant expression (5.19/2). However, both Clang and GCC compile it successfully (Ideone).

  • Is this code correct (and there is a mistake in the Standard) or is it incorrect (and there is a bug in both Clang and GCC)?

I also found these interesting discussions about the Standard wording:

Is it possible that a/this program is "ill-formed, no diagnostic required" and that the compilers are allowed to compile it successfully?

1条回答
太酷不给撩
2楼-- · 2019-02-25 21:30

Is this code correct (and there is a mistake in the Standard)

The standard is what decides if a program is "correct" i.e. well-formed. The standard explicitly says that the program is ill-formed.

or is it incorrect (and there is a bug in both Clang and GCC)?

The program is ill-formed (incorrect). Both clang and gcc are standard compliant in their observed behaviour.

Is it possible that a/this program is "ill-formed, no diagnostic required" and that the compilers are allowed to compile it successfully?

Yes. The standard doesn't require that an ill-formed program must fail to compile. It merely requires that the implementation issues at least one diagnostic message, if the program violates the rules. Some rules are not diagnosable, and diagnostic is not required if such rules are violated.

In fact, the rule is considered "not diagnosable" because it would be very difficult for the compiler to prove (in general) that the rule is violated. It is quite typical that "no diagnostic required" rule violations compile successfully.

If an ill-formed program does compile, the standard does not specify how such program should behave.

查看更多
登录 后发表回答