不返回的

Version >= C++ 11

C++ 11 引入了 [[noreturn]] 屬性。它可以用於一個函式,通過執行一個 return 語句來指示函式沒有返回給呼叫者,或者如果它是正文則通過到達結尾(重要的是要注意這不適用於 void 函式,因為它們回到呼叫者,他們只是不返​​回任何值)。這樣的功能可以通過呼叫 std::terminatestd::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