noexcept函数抛出异常会怎么样
# noexcept函数抛出异常会怎么样
noexcept
关键字是向编译器声明此函数不会抛出异常,编译器可以使用此信息来对noexpect
函数启用某些优化。
#include "gtest/gtest.h"
#include "glog/logging.h"
void func()
{
throw std::runtime_error("func error");
}
TEST(test_other, case1)
{
try {
func();
}
catch (const std::exception& e) {
LOG(ERROR) << e.what();
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
对于用例一,func函数并没有声明noexcept
,所以会被try catch捕获
。
接下来我们写用例二:
void func2() noexcept
{
throw std::runtime_error("func error");
}
TEST(test_other, case2)
{
try {
func2();
}
catch (const std::exception& e) {
LOG(ERROR) << e.what();
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
2
3
4
5
6
7
8
9
10
11
12
13
14
在上述代码中,func2
函数声明为noexcept
但抛出了异常,程序不会进入catch
中,而是直接调用std::terminate
,导致程序突然终止。
- 编译器在编译声明了
noexcept
的函数时,会做一些优化,假设函数不会抛出异常,因此可以省略异常处理相关的代码生成,这能提高函数的执行效率。 - 当异常真的发生时,由于没有合适的异常处理机制来妥善处理,就只能终止程序,以防止未定义行为的扩散。
如果一个函数内部调用了其他可能抛出异常的函数,且无法保证能捕获并处理这些异常,就不应该轻易声明为 noexcept
。另外,在 C++ 标准库中,一些操作,如移动构造函数和移动赋值运算符,通常被声明为 noexcept
,以提高性能和保证资源管理的安全性。如果自定义类型的移动操作可能抛出异常,就需要特别小心,否则可能导致程序意外终止。