7

なぜC#で例Aは有効でコンパイル可能であり、例Bはコンパイルされないのに、ラップするだけなのですか?

A

int val = 0;
val = val + Int32.MaxValue +2;

また

int val = Int32.MaxValue;
val++;

B

int val = 0;
val = 2147483647 + 1;

また

int val = 0;
int val = Int32.MaxValue + 1;

構成でcheckedメソッド、ブロック、または属性を使用して明示的にチェックしない限り、デフォルトでは算術例外がチェックされないことをデフォルトで知っています。私の質問は、算術例外がどのように発生するかよりもコンパイラに関連しています。

4

3 に答える 3

17

あなたの B の例は、コンパイル時に定数で折りたたまれており、オーバーフローすることが保証されていることをコンパイラに示しています。

A の例では変数を使用しているため、式を (完全に) 定数で折りたたむことができないため、コンパイラは値がオーバーフローになることを保証できません。

例えば...

int val = 0;
// some other thread changes `val` to -5...
val = val + Int32.MaxValue +2; // no overflow

ただし、それが変わらないことがわかっている場合は、 に 0 を割り当てます。valconst int

const int startval = 0;
int val = startval + Int32.MaxValue + 2;

値を完全に決定できるため、定数を折りたたむことができるため、コンパイル時のオーバーフロー チェックを元に戻すことができます。

于 2010-07-16T16:22:18.570 に答える
3

構成でcheckedメソッド、ブロック、または属性を使用して明示的にチェックしない限り、算術例外はデフォルトではチェックされないことを私は知っています

そのステートメントが間違っているので、あなたはそれを知りません。実際、あなたは自分の主張が間違っていると証明されたケースを提供したので、それが間違っていることを知っています!

C# 仕様のセクション 7.6.12 を参照してください。便宜上、その一部をここに再現します。

チェックまたはチェックされていない演算子またはステートメントで囲まれていない非定数式 (実行時に評価される式) の場合、外部要因 (コンパイラ スイッチや実行環境の構成など) によって呼び出されない限り、既定のオーバーフロー チェック コンテキストはチェックされません。チェック評価。

定数式 (コンパイル時に完全に評価できる式) の場合、デフォルトのオーバーフロー チェック コンテキストが常にチェックされます。定数式がチェックされていないコンテキストに明示的に配置されていない限り、式のコンパイル時の評価中に発生するオーバーフローは常にコンパイル時エラーを引き起こします。

詳細については、仕様を参照してください。

于 2010-07-16T16:43:04.767 に答える
1

これは、コンパイル時のチェックの制限に関係しています。特定のことは、実行時にのみ知ることができます。

于 2010-07-16T16:23:22.007 に答える