Статический анализатор Xcode 4 сообщает в моем коде некоторые ложные срабатывания. Есть ли способ их подавить?
Можно ли подавить предупреждения статического анализатора Xcode 4?
Ответ 1
Я нашел решение: ложных срабатываний (например, шаблона проектирования одноэлементного Apple) можно избежать:
#ifndef __clang_analyzer__
// Code not to be analyzed
#endif
Анализатор не будет анализировать код между этими препроцессорными директивами.
Ответ 2
Взгляните на эту страницу, в которой показано, как использовать несколько #defines для аннотирования методов и параметров objective-c, чтобы помочь статическому анализатору (clang) сделать правильную вещь
http://clang-analyzer.llvm.org/annotations.html
С этой страницы:
Интерфейс Clang поддерживает несколько аннотаций на уровне исходного кода в форма атрибутов стиля GCP и прагмы, которые могут помочь сделать Статический анализатор Clang более полезен. Эти аннотации могут помочь подавлять ложные срабатывания, а также повышать способность анализатора к найти ошибки.
Ответ 3
Смотрите мой ответ здесь. Вы можете добавить флаг компиляции в файлы, и статический анализатор будет игнорировать их. Вероятно, это лучше для стороннего кода, который вас не волнует, а не для первого кода, который вы пишете.
Ответ 4
большую часть времени, используя такие вещи, как CF_RETURNS_RETAINED и следуя за правилом "create", работает для меня, но я столкнулся с ситуацией, которую я НЕ мог подавить. Наконец нашел способ подавить анализатор, посмотрев исходный код 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).