2017-10-10 51 views
2

我正在做一個小的錯誤處理系統,我想做一個致命的錯誤,終止程序。我想到兩個辦法做到這一點:可以拋出一個noreturn noexcept函數而不是調用std :: terminate嗎?

[[noreturn]] inline void fatal_error1(char const* msg) { 
    std::terminate(); 
} 

[[noreturn]] inline void fatal_error2(char const* msg) noexcept { 
    throw std::runtime_error{msg}; 
} 

有沒有使用,爲什麼會fatal_error2不推薦理由嗎?該功能的目標是終止程序,我甚至將其標記爲noreturn,但每個人似乎都告訴我不要拋出noexcept函數。

我很想使用fatal_error2,因爲它在終端輸出what(),而我需要在該標頭中包含一些輸出功能來打印fatal_error1中的消息。

+1

std :: terminate()方法有問題嗎?如果不是,你爲什麼要尋找替代品? – Borgleader

+2

第二種方法不推薦,因爲它與第一種方法相同,但不是明顯的方式。 – StoryTeller

+0

@Borgleader well ...在第一個版本中,我必須包含'iostream'來輸出一個錯誤,而在大多數系統中異常版本輸出'what()'。這可能不是選擇'fatal_error2'的最好理由,但是這個錯誤處理函數在我的程序中很多地方都會用到,而且我不想在所有地方都包含'iostream',甚至不需要'stdio '。 –

回答

7

是否有理由不推薦使用fatal_error2?

如果您想致電std::terminate - 就這麼做。這是最好的做法,因爲它遵循the principle of least surprise

fatal_error2被聲明爲noexcept但它引發了一個異常,這使得代碼的讀者懷疑作者的意圖。


我很想用fatal_error2因爲它

這似乎在終端輸出what() ...不會是一個很好的藉口,因爲:

  1. 這功能不是可移植的,並且不是C++標準所要求的。
  2. 你可以自己動手做std::cerr << msg << std::endlfprintf(stderr, ...)。而且,這再一次讓你的意圖向讀者明示。
+0

我編輯了這個問題,加入了我使用'fatal_error2'的誘惑背後的動機。 –

+0

不可攜帶確實是一個很大的缺點,也正確地表達了這個意圖。我必須權衡利弊。謝謝你的提示! –

1

是的,沒關係。

最終的結果是,您正在執行您有未處理的異常。 (未處理的異常與從noexcept範圍引發的異常相同)

這與沒有可捕獲您投擲的異常的catch塊相同。就像您在文章中提到的那樣,當程序終止時,您可能會獲得有關未捕獲異常的信息,這可能很有用。

有些人可能會說,最好寫信給std::err,然後致電std::terminate。我不會反駁它,但它確實需要#include <iostream>。你的電話是否比要求#include <stdexcept>好。

+0

換句話說,我仍然必須包括一些東西,這打敗了我最初的動機。但是,具有與未捕獲的異常相同的行爲使其非常吸引人。不僅用於輸出,還用於調試。 –

相關問題