2017-09-01 11 views
-1

例コード:なぜコンパイラはEnvironment.Exitが返すことができると思いますか?

switch(something) 
{ 
    case 0: 
     System.Environment.Exit(0); 
    case 1: 
     // blah ... 
     break; 
} 

コンパイラは、その実行が終了()から復帰することができると考えているのでそれはコンパイルされません。コンパイラは明らかに間違っています。

トリックはありません。 System.Environment.Exit()は本当のものです。

System.Environment.Exit()が返ってくるのはまったく論理的ではないだけでなく、コードをトレースして最終的に返すことができないExitProcess(exitCode);を呼び出します。

+0

コンパイラはメソッドのILを調べて実行時に何が実行されるかを知ることができないため(コンパイラが実行時にどのようなアセンブリがロードされるかを知る方法が全くないため)、*与えられたメソッドが返されないことをコンパイラに提案する –

+0

@AlexeiLevenkov:現在の状況を考えると、[System.Runtime.InteropServices.NoReturn] void Exit(int ExitCode);私がこれを新たに書いていたなら、到達不能を意味するタイプ(System.Voidに似ています)があります。 – Joshua

+0

属性はメソッドシグネチャの一部ではありません。コンパイラは、そのメソッドを実装するためにロードされた実行時ライブラリが属性を持つことを保証することはできません(コンパイラとJITが動作何とかその属性の)。実際、メソッドシグネチャの一部である特別な型を返すが、プロセスを終了するメソッドのこの単一の特別なケースでは、そのメソッドが返すことができないことを検証する追加のインフラストラクチャ全体を構築する価値はあるだろうか? –

答えて

6

言語に関する限り、それは戻ることができます。はい、実生活ではプロセスは復帰する前に終了しますが、コンパイラはメソッドのシグネチャに基づいてそのことを知りません。

「ブレーク」を追加してコンパイラを幸せにする必要があります。

+0

この答えが間違っていることを正確に説明するのは難しいです。なぜそうではなく、何に答えているかのようなものです。 – Joshua

+0

「Foo」という名前の、System.Environment.Exit()というメソッドがあるとします。 'switch'文が' Foo() 'を呼び出した後に' break'を呼び出すようにするか、switch文が 'Foo'の意味を理解すると期待しますか?プロセスは戻ってきませんでしたか? – Tim

+0

コンパイラはライブラリ呼び出しの副作用に依存すべきではありません。この特定の呼び出しは動作することは保証されていませんが、例外をスローする可能性があります。 –

関連する問題