2012-05-16 38 views
5

像下面給出代碼:在C++中對int進行文字賦值是否會引發異常?

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

是有可能的系統可以拋出一個異常,由於簡單的任務?

[編輯:對於那些說,「沒有例外不會發生,」你可以指向我的C++標準的部分方向說這個?我很難找到它。]

+6

是總是'int'的類型,而RHS總是一個文字?還是你問一般情況? (也是你展示的不是任務) – Flexo

+0

感謝您捕捉這一點。我編輯了這個例子。實際上,對於你的第一個問題,對於兩者。 –

回答

7

雖然你可能很難在標準中找到它的保證,但一個簡單的經驗法則是,在C中合法的任何東西都可能無法拋出。 [編輯:最近我知道的一個直接聲明這種效果是§15/ 2,其中說:

代碼執行拋表達被說成「拋出一個異常;」 [...]

看,在相反的,即不執行擲表達式不拋出異常代碼]

投擲基本上限於兩種可能性:第一種是調用UB。第二種方法是執行C++特有的操作,如分配給重載operator =的用戶定義類型或使用new表達式。

編輯:就任務而言,有很多方法可以拋出。顯然,投入運營商本身就可以做到,但也有相當數量的其他運營商。舉例來說,如果源類型與目標類型不匹配,您可能會通過源代碼中的轉換運算符或目標中的構造函數獲得轉換 - 其中任何一種都可能會導致轉換。

+0

實現可以自由限制資源,不是嗎?如果他們不會「沒有更多的堆棧和沒有註冊的備用」(至少在理論上)是一個有效的理由,並且只在第一次使用時才被發現? – Flexo

+0

理論上是。 VC++ 6(舉一個例子)做了這樣的事情 - 但是它效果不佳,VC++不再使用,而且我很快就會發現其他人很快就會嘗試它。 –

+0

@JerryCoffin關於「C中的合法」的充分嚴格的定義。將一個浮點賦值給一個int可能會導致未定義的行爲,並且在未定義行爲的情況下,異常與​​其他任何異常一樣有效(儘管可能不是從實現的角度來看)。 –

0

如果它只是一個int,那麼沒有 - 它不會拋出。

如果它更復雜一些,比如向量,那麼它可能會出於多種原因(例如,分配失敗或從輔助線程中的變更)。

+0

分配失敗定義爲拋出異常(除非您使用的是自定義分配器)。在修改它時訪問另一個線程中的矢量是未定義的行爲,並且可能發生任何事情。然而,從實施質量的角度來看,我並不期望有例外。 –

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, §5.17說「該表達式隱式轉換爲 cv-unqualified類型的左操作數。「根據右操作數的實際類型 :

  • 如果它是一個整數類型,如果實際值不能在int表示,結果是實現定義(C標準更加明確:它必須導致帶有實現定義值的int,否則將得到實現定義的信號)

  • 如果它是浮點值,則結果是未定義行爲,如果無法表示截斷爲零後的值在int中,行爲是未定義的(因此您可能會遇到異常)

  • 如果它是用戶定義的類型,則將調用用戶定義的轉換運算符。哪個可以拋出異常。

如果您關注有關分配其他類型的:每一組 非類類型的,有像上述規則的列表,但唯一 可能的例外會像的結果類型轉換。對於 類型,將使用operator=。哪個可以拋出異常,根據其中的內容而定, 。

相關問題