2017-09-01 66 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

就語言而言,它可以返回。是的,在現實生活中,過程將在它有機會返回之前終止,但編譯器不知道基於方法簽名。

您需要在其中添加「break」以使編譯器很高興。

+0

這個答案很難解釋到底是什麼問題。這幾乎就像是在回答什麼,而不是爲什麼。 – Joshua

+0

想象一下你有一個名爲'Foo'的方法,它叫做System.Environment.Exit()。你會期望'switch'語句強制你在調用'Foo()'後調用'break',或者你希望switch語句通過檢查它的代碼路徑來理解'Foo'的含義以知道它會終止該過程並不能返回? – Tim

+0

編譯器不應該依賴庫調用的副作用。這個特殊的調用不能保證工作,它可以拋出異常。 –

相關問題