在 C++ 中,有时会定义一个变量,但不会使用它。这是一个示例 - 一个用于使用的函数COM_INTERFACE_ENTRY_FUNC_BLIND http://msdn.microsoft.com/en-us/library/5b6w5bwx(VS.80).aspxATL宏:
HRESULT WINAPI blindQuery( void* /*currentObject*/, REFIID iid, void** ppv, DWORD_PTR /*param*/ )
{
DEBUG_LOG( __FUNCTION__ ); //DEBUG_LOG macro expands to an empty string in non-debug
DEBUG_LOG( iid );
iid; // <<<<<<<----silence compiler warning
if( ppv == 0 ) {
return E_POINTER;
}
*ppv = 0;
return E_NOINTERFACE;
}
在上面的例子中iid
参数与DEBUG_LOG
在非调试配置中扩展为空字符串的宏。因此注释掉或删除iid
签名中的变量名不是一个选项。当编译非调试配置时,编译器会生成一个C4100: 'iid' : unreferenced formal parameter
警告,因此为了消除警告iid;
添加了被认为是无操作的语句。
问题如下:如果我们有以下任何声明:
CSomeType variableName; //or
CSomeType& variableName; //or
CSomeType* variableName;
将在 C++ 代码中执行以下语句:
variableName;
始终是一个空操作,独立于什么CSomeType
is?
是的,但您可能会收到另一个警告。
执行此操作的标准方法是:(void)iid;
.
从技术上讲,这仍然可以加载iid
进入寄存器并且什么也不做。诚然,这在编译器方面是极其愚蠢的(我怀疑任何人都会这样做,如果它确实删除了编译器),但如果要忽略的表达式涉及可观察行为,例如调用 IO 函数或的阅读和写作volatile
变量。
这就提出了一个有趣的问题:我们可以采用一个表达式并完全地忽略它?
也就是说,我们现在拥有的是这样的:
#define USE(x) (void)(x)
// use iid in an expression to get rid of warning, but have no observable effect
USE(iid);
// hm, result of expression is gone but expression is still evaluated
USE(std::cout << "hmmm" << std::endl);
这接近于一个解决方案:
罢工>
// sizeof doesn't evaluate the expression
#define USE(x) (void)(sizeof(x))
但失败了:
void foo();
// oops, cannot take sizeof void
USE(foo());
解决方案很简单:
// use expression as sub-expression,
// then make type of full expression int, discard result
#define USE(x) (void)(sizeof((x), 0))
这保证不进行任何操作。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)