1

Apple LLVM 4.2 (XCode 4.6) では、静的アナライザーは、このクラスの 'update' メソッドで「'>' の左オペランドはガベージ値です」と警告します。

Test.h

#import <Foundation/Foundation.h>

typedef struct {
    float x;
} TestInnerStruct;

typedef struct {
    TestInnerStruct innerStruct;
    int value;
} TestOuterStruct;

@interface Test : NSObject {
    TestOuterStruct outerStruct;
}

@end

Test.m

#import "Test.h"

@implementation Test

- (id) init {
    if (self = [super init]) {
        outerStruct.value = 1;
    }
    return self;
}

- (void) update {
    outerStruct.innerStruct = (TestInnerStruct){0.0f};
    if (outerStruct.value > 0) {
        NSLog(@"Value greater than zero");
    }
}

@end

これは、この静的アナライザーの警告を再現するために必要な最小限に実際のクラスを削減することによって作成された、不自然なクラスです。実際のクラスでは、ネストされた構造体を使用する正当な理由があります。

そのオペランドがガベージ値になる原因となるコードのパスはどれですか? それとも、静的アナライザーが混乱していますか?

明確化のために編集: アナライザーが [super init] が nil を返す場合を考慮しているだけではありません。更新メソッドの最初の行をコメントアウトすると警告が消えるため、私はそれを知っています。

4

2 に答える 2

1

self = [super init] が成功した場合、outerStruct.value は 1 にのみ設定されます。そうでない場合 (これはもちろん非常にまれなイベントですが、可能です。そうでない場合は必要ありません)、値は設定されていませんが、ゴミです。

于 2013-01-29T12:30:34.597 に答える
1

エリックは正しく、それは明らかにコンパイラの問題です: TestOuterStruct の定義を

typedef struct {
    int value;
    TestInnerStruct innerStruct;
} TestOuterStruct;

つまり、2 つの要素が交換された場合、コードはエラーなしでコンパイルされます。

于 2013-01-29T16:45:32.187 に答える