不返回的
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