我曾经看过一段代码如下,
/** Starts a synchronized block
*
* This macro starts a block synchronized on its argument x
* Note that the synchronized block defines a scope (i.e. { })
* All variables declared in it will live inside this block only
*/
#define SYNCHRONIZE_ON(x) { \
const abcd::LockBase & __lock = \
abcd::MakeLock(x); __lock;
/** Ends a synchronized block */
#define END_SYNCHRONIZE }
Run Code Online (Sandbox Code Playgroud)
的SYNCHRONIZE_ON和END_SYNCHRONIZE一起用来在物体上同步.宏在它的块中SYNCHRONIZE_ON定义了一个变量____lock.
这里的问题是:句子__lock;(之后abcd::MakeLock(x);)是什么?请注意,该句子仅包含变量名称.
图片你有这个代码:
SYNCHRONIZE_ON(myVariable)
// Do stuff
END_SYNCHRONIZE
Run Code Online (Sandbox Code Playgroud)
它将被重写为:
{
abcd::LockBase& __lock = abcd::MakeLock(myVariable);
__lock;
// Do stuff
}
Run Code Online (Sandbox Code Playgroud)
实际上这个__lock变量不会在你的代码中使用,它只会在它超出范围时处理临界区(如果它是它使用的那个).
该代码的问题在于它会生成大量警告,因为__lock已声明但从未使用过.该语句用于防止这些警告,并且它将被编译器优化(因为它没有副作用),这是您的编译器实际执行的:
{
abcd::LockBase& __lock = abcd::MakeLock(myVariable);
// Do stuff
}
Run Code Online (Sandbox Code Playgroud)
编辑
此代码应该禁止"未使用的变量"警告,但它可能无法从"表达无效"警告中保存.pragmas禁用特定警告根本不可移植,互联网上有很多可以避免它们的解决方法,就像这样(它似乎在编译器之间非常便携).
{
abcd::LockBase& __lock = abcd::MakeLock(myVariable);
(void)__lock;
// Do stuff
}
Run Code Online (Sandbox Code Playgroud)
在这种情况下,更好的解决方案可能是拆分声明和锁定获取,如下所示:
{
abcd::LockBase& __lock = abcd::MakeLock(myVariable);
__lock.Acquire();
// Do stuff
}
Run Code Online (Sandbox Code Playgroud)