bugprone-empty-catch¶
检测并建议解决空 catch 语句的问题。
try {
// Some code that can throw an exception
} catch(const std::exception&) {
}
在代码库中使用空 catch 语句可能是一个严重问题,开发人员应该意识到这一点。catch 语句用于处理程序执行期间抛出的异常。当抛出异常时,程序会跳转到与异常类型匹配的最近的 catch 语句。
空 catch 语句,也称为“吞掉”异常,会捕获异常,但不会对其进行任何处理。这意味着异常没有被正确处理,程序继续运行,就好像什么也没发生一样。这可能导致以下几个问题,例如
隐藏的错误:如果捕获并忽略了异常,则可能导致难以诊断和修复的隐藏错误。问题的根本原因可能不明显,程序可能继续以意想不到的方式运行。
安全问题:忽略异常可能导致安全问题,例如缓冲区溢出或空指针解除引用。黑客可以利用这些漏洞来获取敏感数据或执行恶意代码。
糟糕的代码质量:空 catch 语句可能表明代码质量低下,缺乏对细节的关注。这可能使代码库难以维护和更新,从而导致更长的开发周期和更高的成本。
不可靠的代码:忽略异常的代码通常不可靠,可能导致不可预测的行为。这可能会让用户感到沮丧,并损害对软件的信任。
为了避免这些问题,开发人员应该始终正确处理异常。这意味着修复导致异常的根本问题或将异常向上传播到调用堆栈中更高层的处理程序。如果异常不重要,也应该以某种方式记录或报告它,以便可以跟踪和解决它。
如果异常可以在本地处理,则应该在 catch 块中处理它。这可能涉及记录异常或采取其他适当的措施以确保异常不会被忽略。
以下是一个例子
try {
// Some code that can throw an exception
} catch (const std::exception& ex) {
// Properly handle the exception, e.g.:
std::cerr << "Exception caught: " << ex.what() << std::endl;
}
如果异常无法在本地处理,需要向上传播到调用堆栈,则应该重新抛出异常或抛出新的异常。
以下是一个例子
try {
// Some code that can throw an exception
} catch (const std::exception& ex) {
// Re-throw the exception
throw;
}
在某些情况下,可能不需要在此级别捕获异常,可以将异常向上传播到调用堆栈。这可以通过简单地不使用 try/catch
块来实现。
以下是一个例子
void function() {
// Some code that can throw an exception
}
void callerFunction() {
try {
function();
} catch (const std::exception& ex) {
// Handling exception on higher level
std::cerr << "Exception caught: " << ex.what() << std::endl;
}
}
避免空 catch 语句的另一种潜在解决方案是修改代码以避免首先抛出异常。这可以通过使用不同的 API、事先检查错误条件或以不涉及异常的不同方式处理错误来实现。通过消除对 try-catch 块的需求,代码变得更简单,更不容易出错。
以下是一个例子
// Old code:
try {
mapContainer["Key"].callFunction();
} catch(const std::out_of_range&) {
}
// New code
if (auto it = mapContainer.find("Key"); it != mapContainer.end()) {
it->second.callFunction();
}
总之,空 catch 语句是一种不良做法,可能导致隐藏的错误、安全问题、糟糕的代码质量和不可靠的代码。通过正确处理异常,开发人员可以确保其代码健壮、安全且可维护。
选项¶
- IgnoreCatchWithKeywords¶
此选项可用于忽略包含某些关键字的特定 catch 语句。如果
catch
语句体包含(不区分大小写)此以分号分隔的选项中列出的任何关键字,则将忽略该 catch,不会发出警告。默认值:@TODO;@FIXME.
- AllowEmptyCatchForExceptions¶
此选项可用于忽略特定异常类型的空 catch 语句。默认情况下,如果检测到空 catch 语句,无论捕获的异常类型如何,检查都会发出警告。但是,在某些情况下,例如当开发人员想要有意忽略某些异常或以其他方式处理它们时,可能希望允许特定异常类型的空 catch 语句。要配置此选项,应提供一个以分号分隔的异常类型名称列表。如果列表中的异常类型名称在空 catch 语句中被捕获,则不会发出警告。默认值:空字符串。