【问题标题】:Is it possible to suppress Xcode 4 static analyzer warnings?是否可以抑制 Xcode 4 静态分析器警告?
【发布时间】:2011-08-13 22:45:23
【问题描述】:

Xcode 4 静态分析器在我的代码中报告了一些误报。有什么办法可以压制他们?

【问题讨论】:

  • 误报是可能的,但很少见。请发布您的代码。
  • 使用 Apple 单例设计模式(参见“Cocoa 基础指南”的Creating a Singleton Instance),分析器给出“在第 XX 行分配的对象的潜在泄漏”。
  • 可以说,依赖单例的设计应该得到静态分析器消息。 :-)
  • 这是一个很好的问题。它询问的是如何逐个禁用警告,而不是如何设计软件或是否应该避免单例。单例也不是分析器发生这种情况的唯一情况。这种情况下的“误报”通常是指分析器认为存在潜在内存泄漏的情况,但开发人员知道得更清楚,因为他/她可以比编译器更抽象地思考。
  • 示例:在此处搜索 strcat 和 strcpy:boost.org/doc/libs/1_56_0/boost/regex/v4/regex_workaround.hpp

标签: objective-c xcode4 clang clang-static-analyzer


【解决方案1】:

大多数时候,使用 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)。

【讨论】:

    【解决方案2】:

    查看我的回答here。您可以在文件中添加编译标志,静态分析器将忽略它们。这可能更适合您不关心的第 3 方代码,而不适合您正在编写的第一方代码。

    【讨论】:

      【解决方案3】:

      看看这个页面,它展示了如何使用几个#defines来注释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;
      【解决方案4】:

      我找到了解决方案:可以通过以下方式避免误报(如 Apple 单例设计模式):

      #ifndef __clang_analyzer__
      
      // Code not to be analyzed
      
      #endif
      

      分析器不会分析这些预处理器指令之间的代码。

      【讨论】:

      • 这会不会导致代码在分析时根本不编译?
      • __clang_analyzer__ 是一个宏,在为分析器编译程序时定义(参见Clang User's Manual)。当它被定义时,#ifndef#endif 之间的代码没有被编译,这意味着分析器看不到它。然而,当程序没有为分析器编译时,宏没有定义,代码被正常编译。
      • 某事告诉我,如果您取出部分代码,它可能无法编译。或者你需要一个#else 中的存根。我说的对吗?
      猜你喜欢
      • 2011-06-24
      • 1970-01-01
      • 2015-10-22
      • 1970-01-01
      • 1970-01-01
      • 2010-12-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多