像下面給出代碼:在C++中對int進行文字賦值是否會引發異常?
void f()
{
int i;
i = 0;
}
是有可能的系統可以拋出一個異常,由於簡單的任務?
[編輯:對於那些說,「沒有例外不會發生,」你可以指向我的C++標準的部分方向說這個?我很難找到它。]
像下面給出代碼:在C++中對int進行文字賦值是否會引發異常?
void f()
{
int i;
i = 0;
}
是有可能的系統可以拋出一個異常,由於簡單的任務?
[編輯:對於那些說,「沒有例外不會發生,」你可以指向我的C++標準的部分方向說這個?我很難找到它。]
雖然你可能很難在標準中找到它的保證,但一個簡單的經驗法則是,在C中合法的任何東西都可能無法拋出。 [編輯:最近我知道的一個直接聲明這種效果是§15/ 2,其中說:
代碼執行拋表達被說成「拋出一個異常;」 [...]
看,在相反的,即不執行擲表達式不拋出異常代碼]
投擲基本上限於兩種可能性:第一種是調用UB。第二種方法是執行C++特有的操作,如分配給重載operator =
的用戶定義類型或使用new
表達式。
編輯:就任務而言,有很多方法可以拋出。顯然,投入運營商本身就可以做到,但也有相當數量的其他運營商。舉例來說,如果源類型與目標類型不匹配,您可能會通過源代碼中的轉換運算符或目標中的構造函數獲得轉換 - 其中任何一種都可能會導致轉換。
實現可以自由限制資源,不是嗎?如果他們不會「沒有更多的堆棧和沒有註冊的備用」(至少在理論上)是一個有效的理由,並且只在第一次使用時才被發現? – Flexo
理論上是。 VC++ 6(舉一個例子)做了這樣的事情 - 但是它效果不佳,VC++不再使用,而且我很快就會發現其他人很快就會嘗試它。 –
@JerryCoffin關於「C中的合法」的充分嚴格的定義。將一個浮點賦值給一個int可能會導致未定義的行爲,並且在未定義行爲的情況下,異常與其他任何異常一樣有效(儘管可能不是從實現的角度來看)。 –
如果它只是一個int
,那麼沒有 - 它不會拋出。
如果它更復雜一些,比如向量,那麼它可能會出於多種原因(例如,分配失敗或從輔助線程中的變更)。
分配失敗定義爲拋出異常(除非您使用的是自定義分配器)。在修改它時訪問另一個線程中的矢量是未定義的行爲,並且可能發生任何事情。然而,從實施質量的角度來看,我並不期望有例外。 –
它只能在一種情況下拋出異常:當這兩種類型的拋出過載operator=()
;相似的,當需要轉換時,轉換構造函數或operator T()
也可以拋出。這取決於確切的實現 - 然後找出它是否會拋出,在您正在使用的庫的文檔中查找有關它的信息。
有相當多的東西,看起來像會拋出這樣或那樣的任務:
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的新的)
如果你很在意將0
(其類型爲int
)分配給 int
,該標準的§5.17非常精確地指定了 賦值操作的語義,並且不存在可能發生異常的情況。 如果您擔心將任意表達式分配給int
, §5.17說「該表達式隱式轉換爲 cv-unqualified類型的左操作數。「根據右操作數的實際類型 :
如果它是一個整數類型,如果實際值不能在int
表示,結果是實現定義(C標準更加明確:它必須導致帶有實現定義值的int
,否則將得到實現定義的信號)
如果它是浮點值,則結果是未定義行爲,如果無法表示截斷爲零後的值在int
中,行爲是未定義的(因此您可能會遇到異常)
如果它是用戶定義的類型,則將調用用戶定義的轉換運算符。哪個可以拋出異常。
如果您關注有關分配其他類型的:每一組 非類類型的,有像上述規則的列表,但唯一 可能的例外會像的結果類型轉換。對於 類型,將使用operator=
。哪個可以拋出異常,根據其中的內容而定, 。
是總是'int'的類型,而RHS總是一個文字?還是你問一般情況? (也是你展示的不是任務) – Flexo
感謝您捕捉這一點。我編輯了這個例子。實際上,對於你的第一個問題,對於兩者。 –