在 Linux 下用 C++ 做异常处理,本质上就是使用 C++ 标准异常机制(try / catch / throw),再结合 Linux 特有的一些信号、系统调用错误处理方式。下面分层说明。
#include <iostream>
#include <stdexcept>
void foo(int x) {
if (x < 0)
throw std::invalid_argument("x must >= 0");
}
int main() {
try {
foo(-1);
} catch (const std::exception& e) {
std::cerr << "Exception: " << e.what() << std::endl;
} catch (...) {
std::cerr << "Unknown exception" << std::endl;
}
return 0;
}
<stdexcept>)std::runtime_errorstd::logic_errorstd::out_of_rangestd::invalid_argumentclass MyException : public std::runtime_error {
public:
explicit MyException(const std::string& msg)
: std::runtime_error(msg) {}
};
在 GCC / Clang 下:
g++ -std=c++17 -O2 main.cpp -o main
✅ 现代 GCC 默认开启异常
❌ 不要加 -fno-exceptions(除非你明确不用异常)
errnoLinux 系统调用失败通常:
-1errno示例:
#include <cerrno>
#include <cstring>
#include <stdexcept>
int fd = open("file", O_RDONLY);
if (fd < 0)
throw std::runtime_error(strerror(errno));
C++ try/catch 不能捕获 Linux 信号。
#include <csignal>
#include <csetjmp>
jmp_buf env;
void handler(int) {
longjmp(env, 1);
}
int main() {
signal(SIGSEGV, handler);
if (setjmp(env) == 0) {
// 可能崩溃的代码
} else {
// 处理“异常”
}
}
⚠️ 不推荐新手用,容易破坏程序状态
✅ 更推荐:
Linux 下资源(文件、socket、锁)必须用 RAII:
#include <fstream>
void func() {
std::ofstream f("a.txt");
// 即使抛异常,f 也会自动关闭
}
或自定义:
class FileGuard {
FILE* fp;
public:
FileGuard(const char* name) {
fp = fopen(name, "r");
if (!fp) throw std::runtime_error("open failed");
}
~FileGuard() { if (fp) fclose(fp); }
};
g++ -g main.cpp
./a.out
# 崩溃时用 gdb
gdb ./a.out core
#include <exception>
void myTerminate() {
std::cerr << "Unhandled exception\n";
abort();
}
int main() {
std::set_terminate(myTerminate);
}
g++ -fsanitize=address -g main.cpp
✅ 用 std::exception 派生异常
✅ 用 catch(const std::exception&)
✅ 用 RAII 管理资源
✅ 系统调用失败转异常
❌ 不要用异常代替逻辑判断
❌ 不要试图 catch SIGSEGV
如果你愿意,我可以:
你更想看哪一种?