2012-05-16 1 views
5

C++でintに代入すると例外がスローされますか?次のようなコードが与えられ

void f() 
{ 
    int i; 
    i = 0; 
} 

は、それはシステムが単純な代入のために例外をスローする可能性が可能ですか?

[編集:「例外は発生しません」と言っている人は、これを言うC++標準の部分に私を向けることができますか?私はそれを見つけるのが難しいです。]

+6

は常に型intで、RHSは常にリテラルですか?それとも一般的な事例について聞いていますか? (あなたが示したことは割り当てではありませんでした) – Flexo

+0

その点をキャッチしてくれてありがとう。私はその例を編集した。あなたの最初の質問に、両方のために、実際に。 –

答えて

7

標準でそれを保証するのは難しいかもしれませんが、簡単な経験則では、Cで正当なものは投げられない可能性があります。 [編集:スロー表現を実行

コードは「例外をスローするように言われます。私はこの効果への直接陳述の承知している最も近いことを言っている、§15/ 2であるが;」[...]

逆にそれを見ると、例外をスローしませんスロー式を実行しないコード]投てきは基本的に2つの可能性に制限されている

:最初は、 UBを呼び出す。 2番目は、C++に固有の何かをしています。たとえば、operator =をオーバーロードするユーザー定義型に割り当てるか、new式を使用します。

編集:割り当てが行われる限り、スローできる方法はかなりあります。明らかに、代入演算子自体を投げ入れることはできますが、かなりの数の他のものがあります。たとえば、ソース・タイプがターゲット・タイプと一致しない場合は、ソース内のキャスト演算子またはターゲット内のコンストラクタを介して変換が行われる可能性があります。

+0

実装はリソースに制限を課すことは自由ですか?もし彼らが「スタックしていなくてもレジスタはありません」(少なくとも論理的には)投げて正当な理由があれば、最初の使用時にしか見つからないでしょうか? – Flexo

+0

理論上はい。 VC++ 6(一例として)はそういったことをしましたが、VC++がそれ以上の機能を果たさないほどうまく機能しませんでした。そして、誰か他の誰かがすぐにそれを試みるのを見るのはちょっと驚きました。 –

+0

@JerryCoffin "Cの正当"を十分に厳密に定義しています。浮動小数点をintに代入すると、未定義の動作が発生する可能性があります。また、例外は未定義のビヘイビアの場合と同じように有効です(実装の観点からは多分ではありません)。 –

0

もしそれがちょうどintなら、それは投げません。

ベクトルのようなもっと複雑なものなら、いくつかの理由(例えば、割り当ての失敗やセカンダリスレッドからの変更)で投げられる可能性があります。

+0

割り当ての失敗は、(カスタムアロケータを使用していない限り)例外をスローするように定義されています。別のスレッドから変更中にベクトルにアクセスすることは、未定義の動作であり、何かが起こる可能性があります。しかし、実装の品質という観点からは、私は例外を予期しません。 –

2

例外をスローすることができるのは、1つのケースのみです。これらの2つのタイプに対してオーバーロードされたoperator=()がスローされます。同様に、変換が必要な場合は、変換コンストラクタまたはoperator T()もスローすることができます。それは正確な実装に依存します - それがスローされるかどうかを調べるには、使用しているライブラリのドキュメンテーションの情報を探します。

6

一つの方法または別投げることができる割り当てのように見えるものがかなり多くあります:あなたが心配なら

int operator"" _t(const char *) { throw 0; } // C++11 user defined literal 

struct foo { 
    foo(int) { throw 0; } 
    operator int() { throw 0; } 
    foo& operator=(int) { throw 0; } 
}; 

int main() { 
    int i; 
    i = 0; // can't throw 
    i = 0_t; // User defined literal throws 
    foo f = 0; // Constructor throws 
    i = f; // conversion operator throws 
    f = 0; // assignment throws 
    f = f; // both conversion and assignment would like to throw 
} 

(C++ 11から新しいものを含む)

3

は、 0(型がintのもの)を intに代入すると、標準の§5.17は、 割り当て操作のセマンティクスを非常に正確に指定しており、例外が発生することはありません。 intに任意の式を割り当てることを心配している場合、は式が暗黙的に左側のオペランドの cv-unqualifiedタイプに変換されていると言います( §5.17)。「右オペランドの実際のタイプ に応じて:

  • それが整数型である場合、実際の値はintで表現できない場合、結果は実装定義されている(C標準は、より明確です。

  • 浮動小数点値の場合、ゼロに切り捨てた後の値を表現できない場合、結果は未定義の動作になりますintでは、動作は定義されていません(例外が発生する可能性があります)

  • ユーザー定義型の場合は、ユーザー定義の変換演算子が呼び出されます。例外をスローする可能性があります。あなたは、他のタイプの割り当てを懸念している場合は

: 非クラス型の各セットのためには、上記のようなルールのリストがあるが、唯一の 可能性のある例外は、結果のようになりますタイプ変換。クラス の場合、operator=が使用されます。どのような例外がスローされる可能性がありますか?

関連する問題