![](/img/trans.png)
[英]std::bad_alloc exception thrown when operator= method is called C++
[英]How are standard library exception bad_alloc thrown and std::abort called when there is no standard header included?
我注意到如果new
找不到免費存儲 memory 來分配,它會拋出標准庫異常bad_alloc
。
在我的理解中,如果我們沒有捕捉到異常, std::abort
將被調用來終止程序。
所以我嘗試了以下代碼(沒有#include
任何東西):
int main()
{
int* p = new int[99999999999999]; // or any number that is sufficiently large
}
結果表明abort() has been called
。
我知道即使 header 不包括在內,每個翻譯單元中都會隱式聲明new
。
但是,據我了解,如果我們不#include
任何標准 header,則不會定義標准庫異常和std::abort
等設施。
所以,我的問題是,在未定義它們的情況下如何拋出bad_alloc
和std::abort
?
我知道即使不包括 header,也會在每個翻譯單元中隱式聲明 new。
new
是 C++ 中的關鍵字, new int[99999999999999]
是表達式的特定類型,new-expression。 這本質上是核心語言的一部分。 沒有任何意義可以宣布這個new
的。 它只是特定語法結構的關鍵字部分。 這不是 function 調用或類似的調用。
<new>
聲明operator new
的重載,這是一個可以聲明的 function。 但是operator new
與 new 表達式不同。 它們都使用關鍵字new
並且 new 表達式通常調用operator new
重載,但它們是完全不同的東西。
翻譯單元中是否聲明了std::bad_alloc
與 new-expression 是否可以拋出它無關。 new-expression 是核心語言的一部分,標准庫也是語言本身的一部分,不能嚴格分開。 即使沒有包含標准庫 header ,以拋出std::bad_alloc
的方式指定語言也是完全可以的。 從字面上看,從包含 throw 表達式的標准庫 header 中不必包含一些 C++ 代碼。 編譯器可以根據需要插入它。
但是,這里的std::bad_alloc
不是從 new-expression 本身拋出的。 它是由 new 表達式隱式聲明和調用的operator new
拋出的。 如果這是在普通的 C++ 代碼中實現的,那么只需要在實際的throw
表達式放在operator new
的定義中的地方聲明異常類型,而不是在傳播異常的地方聲明。 operator new
的定義通常位於與標准庫實現一起提供的某個動態庫中。
一個更好的例子是std::bad_array_new_length
如果請求的元素數量不是編譯時常量並且在運行時轉換為std::size_t
之前恰好是負數,則它會被例如 array-new-expression 拋出。 即使沒有包含標准庫 header,此異常也會直接從 new-expression 而非operator new
引發。
同樣,因為std::abort
(和std::terminate
)也是標准庫的一部分,因此本質上是語言的一部分,它們仍然可以被調用,例如當沒有捕獲到異常時,即使沒有用戶代碼包括一個標准庫 header ,因此在用戶翻譯單元中沒有 function 的聲明。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.