2016-11-10 90 views
0

假設我具有簽名[[noreturn]] void die(int exit_code);的功能。如果我寫的語句:爲什麼檢查返回類型的[[noreturn]]函數?

check_some_condition() or die(EXIT_FAILURE); 

我得到一個錯誤信息(使用GCC 5.4.0):

error: expression must have bool type (or be convertible to bool) 

偏偏是檢查類型,如果編譯器知道進入該功能,返回值無關緊要;如果條件檢出,返回類型無關緊要?

編輯:關於[[noreturn]]標準的措辭是否沒有解決這一問題,即放寬對類型的要求以使這些表達「合法化」?

+1

那麼,函數'die'不返回'bool'也不可將其轉化爲'bool'一個類型(例如,'int')。你爲什麼期望編譯器能夠將它轉換爲布爾表達式?實際的問題應該是:如果**你知道進入該函數,返回值無關緊要,那麼爲什麼你把它作爲布爾表達式的一部分? –

+1

@TheodorosChatzigiannakis [[noreturn]]根本不是一種類型。這是一個屬性。 – StoryTeller

+0

@StoryTeller:1.忘記輸入'void'。 2.事實上,我希望有一個'[noreturn]]空白'(或[[noreturn]]'什麼)可以「轉換」爲任何類型,因爲你實際上不需要進行轉換,所以你可以安全地認爲這是可能的。 – einpoklum

回答

0

每個表達式都必須有一個確定的類型,句點。因此,即使該函數沒有返回,也仍然可以評估表達式的類型check_some_condition() or die(EXIT_FAILURE)

並且由此得出函數返回類型必須可用於邏輯操作。

+0

問題是,您可以很好地確定表達式的類型,至少就執行該程序而言至關重要:除非是bool,否則由於[[[noreturn]]' 。 – einpoklum

+0

@einpoklum,你並不是說這種類型可以很好地確定,你認爲它是無關緊要的。那些不是一回事。 – StoryTeller

+0

我建議類型的「良好決定」可以[擴展而不是故意](https://en.wikipedia.org/wiki/Extensional_and_intensional_definitions#Intensional_definition),以便在某種程度上濫用這些定義。表情會像鴨子一樣走路,像鴨子一樣嘎嘎,所以它是一隻夠好的鴨子。 – einpoklum

3

noreturn沒有告訴該函數沒有返回值的編譯器。它告訴編譯器該函數不會返回。它對函數的返回類型也沒有影響。

在表達式中,編譯器是必需的,以檢查表達式的操作數具有有效的類型。在類似check_some_condition() or die(EXIT_FAILURE)的表達式中,需要檢查返回類型check_some_condition()die()noreturn不會影響函數的返回類型,因此不會影響該檢查的需要。如果函數返回void,則表達式無效。

+0

那麼,我的理解是它應該影響函數的返回類型,或者至少是涉及函數的表達式的類型。標準中是否包含有關[[noreturn]]的措詞? – einpoklum

+0

我必須檢查確切的寫法,但標準有效地說'noreturn'是函數的一個屬性,而不是它的返回類型。這意味着它不會影響返回類型。 – Peter

+0

「A,這意味着B」 - A不一定意味着B我的朋友:-) – einpoklum

3

你正在尋找的概念被稱爲bottom type。在類型系統中,底部類型是可轉換爲任何其他類型的類型。 (也可將其與所有類型都可兌換的top type進行比較。)

底部類型是不返回函數的完美候選。把它分配給任何東西都是類型安全的,正是因爲分配永遠不會發生。如果C++有一個底部類型,並且如果你聲明你的函數返回底部類型,你的代碼片段可能是完全合法的,你的期望是正確的。

不幸的是,C++不具有這樣的類型。正如已經指出的那樣,[[noreturn]]不是一種類型 - 它是一種用於以與類型系統正交的方式表達意圖(對其他程序員和優化器)的屬性。就類型檢查器而言,函數的返回類型仍然是void,並且不能轉換爲布爾值。