使用未引用的局部变量警告捕获异常

Posted

技术标签:

【中文标题】使用未引用的局部变量警告捕获异常【英文标题】:Catching exception with unreferenced local variable warning 【发布时间】:2014-06-26 10:29:45 【问题描述】:

我有以下代码:

try 
    // do some stuff

catch(const my_exception_type& e) 
    LOG("Exception %s", e.what());
    throw;

问题是在调试版本中LOG 被定义为#define LOG(...) real_logger(...),但在发布版本中被定义为#define LOG(...) \\ do nothing

当然,当我在 Visual Studio 中编译发布代码时,我会得到 warning C4101: 'e' : unreferenced local variable

在不生成任何不必要的警告的情况下处理异常日志的最佳做法是什么?

附注 除了记录并重新抛出它之外,我没有对异常做任何事情。

【问题讨论】:

附带说明,这正是我的 g++/clang++ 编译器需要的行为,以便在我的静态分析工具将其检测为缺陷之前解决此问题......无论如何我启用的详细程度,他们不会警告我。 【参考方案1】:

您可以通过将对象强制转换为 void 来将其标记为“已使用”。 它对生成的机器码没有影响,但会抑制编译器警告。

try 
    // do some stuff

catch(const my_exception_type& e) 
    (void)e;
    LOG("Exception %s", e.what());
    throw;

【讨论】:

有趣的是,Herb Sutter 的另一个sample 正在使用模板函数:template<class T> void ignore( const T& ) 。但是还有其他解决方案吗? 可能有多种方法可以告诉编译器某个对象以某种方式被使用。 void 演员阵容非常有名。 QT 甚至为此提供了宏Q_UNUSED(value),其定义如下:#define Q_UNUSED(x) (void)x; e=e 是另一个常见的成语。 @Clifford:不幸的是,这可能会触发编译器无法优化的自赋值(对于用户定义的类型)。 @MatthieuM。你的代码刚刚抛出了一个异常,也许优化是最不关心的?【参考方案2】:

您可以#ifdef 每条catch 行(非常有侵略性)或在每个catch 块中添加一行:

catch(const my_exception_type& e) 
    UNREFERENCED_PARAMETER(e);
    LOG("Exception %s", e.what());
    throw;

警告消失了。或者,您可以#define MY_EXCEPTION_CATCH(...) 仅在调试版本中定义e 参数。

【讨论】:

#ifdef each catch 行是我试图忽略的东西。添加e;是什么意思?你能详细说明一下吗? 如果在每个 catch 块中添加行 e;,编译器会认为这是 e 变量的“使用”...代码混乱

以上是关于使用未引用的局部变量警告捕获异常的主要内容,如果未能解决你的问题,请参考以下文章

漏洞分析——变量缺陷漏洞及通用异常捕获声明缺陷漏洞

为啥当我在函数中声明一个名称为全局数组的局部数组时,bash 会引发未绑定变量警告?

如何避免 MSVC 警告 C4701:可能未初始化的局部变量

js 基础 -- 循环函数调用 全局和局部变量异常捕获事件

Pycharm - 禁用'局部变量'xxx'可能在分配之前被引用'

分配对局部变量的引用,如果局部变量超出范围,它会超出范围吗?