2017-01-31 2 views
2
#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の機能又は非テンプレートの診断不要(NDR):ConstExpr関数C++で投げる14

、非不履行、非継承引数値は、存在しない場合、constexprのコンストラクタをその関数の呼び出しまたはコンストラクタは、コア定数式(5.19)の評価された部分式である可能性があり、プログラムは不正である。診断は必要ありません。

それは次のように記載されてスロー発現コア定数式(5.19/2)ではないので、「が悪い形成されない診断はを必要としません」。しかし、ClangとGCCの両方が正常にコンパイルします(Ideone)。

  • は、このコード正しいです(とそこに間違いが標準である)、または、それは間違っている(とクランとGCCの両方にバグがありますか)?

私はまた、標準的な文言についてのこれらの興味深い議論が見つかりました:

はそれが可能/このプログラムは、「病気であるということです - 形成され、診断不要 "とコンパイラはそれを正常にコンパイルできますか?

+7

「診断不要」とはどういう意味ですか? – ildjarn

+0

メモリから、clangはスローされた例外をコンパイラエラーとして解釈し、少なくとも標準的な例外をスローするとうまく報告します。私はそれが素敵なタッチだと思った。 –

+0

あなたはあなたがリンクしている "興味深い議論"で答えを見つけることができます。 – molbdnilo

答えて

3

正しいこのコードである(および標準に間違いがある)

標準プログラムは、すなわち、十分に形成された「正しい」である場合を決定するものです。この規格は、プログラムが不正であると明示している。

(またはClangとGCCの両方にバグがあります)

プログラムが不正(不正)です。 clangとgccの両方が、観測された動作に標準で準拠しています。

このプログラムが「不正な形式で診断不要」であり、コンパイラが正常にコンパイルできる可能性はありますか?

はい。この規格では、不正な形式のプログラムをコンパイルできないようにする必要はありません。プログラムが規則に違反している場合、実装が少なくとも1つの診断メッセージを発行することを要求するだけです。いくつかのルールは診断可能ではなく、そのようなルールに違反すると診断は必要ありません。

実際、ルールは、コンパイラがルール違反を(一般的に)証明することは非常に困難なため、「診断不可」とみなされます。「診断不要」ルール違反が正常にコンパイルされることは、非常に一般的です。

悪意のあるプログラムがコンパイルされた場合、そのプログラムはどのように動作するべきかを規定していません。

+0

標準的な設計上の問題として、診断を必要としないことは、これらのルールに違反するプログラムが、この変更の影響を受ける前に有効なプログラムなしでエラーメッセージ*でコンパイルできないことを意味します。コンパイラは診断を追加することができます。標準に準拠すると、その変更に先立つ標準準拠のコードには影響しません。 「病気ではなく、診断は必要ありません」と考えると、標準的な作家がルールを実行するのが好きな標準で発生する傾向がありますが、現時点では簡単な方法はありません。 – Yakk

関連する問題