不返回的
Version >= C++ 11
C++ 11 引入了 [[noreturn]]
屬性。它可以用於一個函式,通過執行一個 return 語句來指示函式沒有返回給呼叫者,或者如果它是正文則通過到達結尾(重要的是要注意這不適用於 void
函式,因為它們回到呼叫者,他們只是不返回任何值)。這樣的功能可以通過呼叫 std::terminate
或 std::exit
或通過丟擲異常來結束。值得注意的是,這樣的函式可以通過執行 longjmp
返回。
例如,下面的函式將始終丟擲異常或呼叫 std::terminate
,因此它是 [[noreturn]]
的一個很好的候選者:
[[noreturn]] void ownAssertFailureHandler(std::string message) {
std::cerr << message << std::endl;
if (THROW_EXCEPTION_ON_ASSERT)
throw AssertException(std::move(message));
std::terminate();
}
這種功能允許編譯器在沒有 return 語句的情況下結束函式,如果它知道程式碼永遠不會被執行的話。這裡,因為在下面的程式碼中對 ownAssertFailureHandler
(上面定義)的呼叫永遠不會返回,所以編譯器不需要在該呼叫下面新增程式碼:
std::vector<int> createSequence(int end) {
if (end > 0) {
std::vector<int> sequence;
sequence.reserve(end+1);
for (int i = 0; i <= end; ++i)
sequence.push_back(i);
return sequence;
}
ownAssertFailureHandler("Negative number passed to createSequence()"s);
// return std::vector<int>{}; //< Not needed because of [[noreturn]]
}
如果函式實際返回,則是未定義的行為,因此不允許以下內容:
[[noreturn]] void assertPositive(int number) {
if (number >= 0)
return;
else
ownAssertFailureHandler("Positive number expected"s); //< [[noreturn]]
}
請注意,[[noreturn]]
主要用於 void 函式。但是,這不是必需的,允許在泛型程式設計中使用這些函式:
template<class InconsistencyHandler>
double fortyTwoDivideBy(int i) {
if (i == 0)
i = InconsistencyHandler::correct(i);
return 42. / i;
}
struct InconsistencyThrower {
static [[noreturn]] int correct(int i) { ownAssertFailureHandler("Unknown inconsistency"s); }
}
struct InconsistencyChangeToOne {
static int correct(int i) { return 1; }
}
double fortyTwo = fortyTwoDivideBy<InconsistencyChangeToOne>(0);
double unreachable = fortyTwoDivideBy<InconsistencyThrower>(0);
以下標準庫函式具有以下屬性:
- std ::中止
- std ::退出
- std::quick_exit
- std ::意外
- std ::終止
- std::rethrow_exception
- std::throw_with_nested
- std::nested_exception::rethrow_nested