1

意図的にコード化された怠惰な初期化:

-(X*) prop {
    if (!prop) {
        prop = [[Prop alloc] init];
        return prop;
    }
    // RETURN SHOULD BE HERE 
}

それにもかかわらず、以下の生成されたコードシーケンスによる「正しいこと」はありますか?

  • テストのために prop を rax にロードする
  • いずれにせよraxを返す
4

2 に答える 2

4

これは意図的なものではありません。たとえうまくいったとしても、それに頼るべきではありません。たとえば、次のことを考慮してください。

- (NSString *)someString {
    if (! someString) {
        someString = [[NSString alloc] initWithFormat:@"%d", 5];
        return someString;
    }
}

でコンパイルした場合gcc -O0:

movq    -24(%rbp), %rdx
movq    _OBJC_IVAR_$_SomeClass.someString@GOTPCREL(%rip), %rax
movq    (%rax), %rax
leaq    (%rdx,%rax), %rax
movq    (%rax), %rax
testq   %rax, %rax

お気づきのように、 ivar が にロードされているため、コードは実際に機能しますRAX

ただし、次のようにコンパイルするとgcc -O3:

    movq    %rdi, %rbx
    addq    _OBJC_IVAR_$_SomeClass.someString(%rip), %rbx
    cmpq    $0, (%rbx)
    je  L5
L4:
    movq    (%rsp), %rbx
    movq    8(%rsp), %r12

おっと、戻り値がありませんRAX— ivar が にロードされましRBXた。このコードは最初の呼び出し (ivar を遅延して初期化する呼び出し) では機能しますが、2 回目の呼び出しではクラッシュします。

于 2011-06-07T09:30:59.140 に答える
2

意図的に、コード化されていない遅延初期化:

いいえ。

標準リターンレジスタが使用されたのは幸運です。絶対に頼らないでください。実際、コンパイラの警告が表示されるはずです。

于 2011-06-07T10:05:36.680 に答える