如何禁止显示来自ON_BLOCK_EXIT的警告(ScopeGuard 的一部分)

How to suppress warnings from ON_BLOCK_EXIT (part of ScopeGuard)

本文关键字:警告 ScopeGuard 一部分 EXIT BLOCK 禁止显示 ON      更新时间:2023-10-16

ON_BLOCK_EXIT是由ScopeGuard实现提供的实用程序宏。它定义本地对象的唯一原因是在超出范围时执行其用户提供的析构函数。它被定义为:

#define CONCATENATE_DIRECT(s1, s2) s1##s2
#define CONCATENATE(s1, s2) CONCATENATE_DIRECT(s1, s2)
#define ANONYMOUS_VARIABLE(str) CONCATENATE(str, __LINE__)
#define ON_BLOCK_EXIT ScopeGuard ANONYMOUS_VARIABLE(scopeGuard) = MakeGuard

并且可以像这样使用:

void foo() {
    HANDLE hFile = CreateFile( ... );
    ON_BLOCK_EXIT( CloseHandle, hFile );
    // more...
    // ... code...
    // ... following
} // warning C4189

使用 Visual Studio 2010 编译时,上面的代码会生成以下warning C4189: 'scopeGuard3' : local variable is initialized but not referenced

#pragma warning( suppress : 4189 )可用于暂时禁用警告。但是,这有两个问题:1.) 它不能放在导致警告的语句旁边,而必须位于结束范围的行的正上方。2.) 作为推论,它将屏蔽当前范围产生的所有警告 4189。

使用

Visual Studio 2010 是否有任何方法可以禁用仅由使用 ON_BLOCK_EXIT 创建的那些对象产生的此特定警告(最好不必更改调用站点,类似于 GCC 的__attribute__((unused)))?

我最终选择的解决方案适用于Visual Studio 2005或更高版本:

#define ON_BLOCK_EXIT( ... ) ScopeGuard ANONYMOUS_VARIABLE(scopeGuard) = 
                                 MakeGuard( __VA_ARGS__ ); 
                                 (void)ANONYMOUS_VARIABLE(scopeGuard)

原始宏未扩展为完整表达式,因此无法追加任何检测来指示编译器不引发警告。使用可变参数宏提供了该选项。