簡體   English   中英

當不包含標准 header 時,如何拋出標准庫異常 bad_alloc 和調用 std::abort?

[英]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_allocstd::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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM