Xcode 4的静态分析器在我的代码中报告了一些虚假阳性。是否有任何方法可以抑制它们?
Xcode 4的静态分析器在我的代码中报告了一些虚假阳性。是否有任何方法可以抑制它们?
我找到了一个解决方案:可以通过以下方式避免错误的正向结果(例如,苹果的单例设计模式):
#ifndef __clang_analyzer__
// Code not to be analyzed
#endif
分析器不会分析那些预处理指令之间的代码。
__clang_analyzer__
是一个宏,当程序被编译为分析器时定义(请参阅Clang用户手册)。
当它被定义时,#ifndef
和#endif
之间的代码不会被编译,这意味着分析器看不到它。但是,当程序未被编译为分析器时,该宏未被定义,代码将像平常一样被编译。 - DreamOfMirrors请看这个页面,它展示了如何使用多个 #define 注释 Objective-C 方法和参数,以帮助静态分析器 (clang) 做正确的事情。
http://clang-analyzer.llvm.org/annotations.html
从该页面:
Clang前端支持多种源级别注释,以GCC样式的属性和预处理指令的形式,这些注释可以帮助更好地使用Clang静态分析器。这些注释既可以帮助抑制误报,也可以增强分析器发现错误的能力。
#ifndef __clang_analyzer__
更好,因为它们适用于方法在任何地方使用的情况。例如:@property (nonatomic, retain) NSString* newString NS_RETURNS_NOT_RETAINED;
- Noah Harrison大多数情况下,像CF_RETURNS_RETAINED这样的东西并遵循“创建”规则对我来说都有效,但我遇到了一个无法抑制的情况。 最终通过查看llvm源代码找到了一种抑制分析器的方法:
https://llvm.org/svn/llvm-project/cfe/trunk/test/ARCMT/objcmt-arc-cf-annotations.m.result
“测试一下当我们存储指向全局变量的指针时是否可以抑制错误。”static CGLayerRef sSuppressStaticAnalyzer;
static CGLayerRef sDmxImg[2][2][1000]; // a cache of quartz drawings.
CGLayerRef CachedDmxImg(...) // which lives for lifetime of app!
{
...
CGLayerRef img = sDmxImg[isDefault][leadingZeroes][dmxVal];
if ( !img )
{
NSRect imgRect = <some cool rectangle>;
[NSGraphicsContext saveGraphicsState];
CGContextRef ctx = (CGContextRef)[[NSGraphicsContext currentContext] graphicsPort];
CGLayerRef cgLayerRef = CGLayerCreateWithContext(ctx, imgRect.size, NULL);
CGContextRef layerCtx = CGLayerGetContext(cgLayerRef);
[NSGraphicsContext setCurrentContext: [NSGraphicsContext graphicsContextWithGraphicsPort:layerCtx flipped:YES]];
... draw some gorgeous expensive Quartz stuff ...
img = cgLayerRef;
sDmxImg[isDefault][leadingZeroes][dmxVal] = cgLayerRef;
sSuppressStaticAnalyzer = cgLayerRef; // suppress static analyzer warning!
[NSGraphicsContext restoreGraphicsState];
}
return img;
}
由于某种原因,给静态数组赋值并没有抑制警告,但是给普通的旧静态'sSuppressStaticAnalyzer'赋值确实做到了。 顺便说一下,使用CGLayerRef上述方法是我发现重新绘制缓存图像最快的方式(除了OpenGL)。