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)中有效,但在第二次调用中崩溃。

于 2011-06-07T09:30:59.140 回答
2

是不是故意的,一个错误编码的惰性初始化:

不。

您很幸运使用了标准返回寄存器。永远不要依赖它。事实上,它应该给你一个编译器警告。

于 2011-06-07T10:05:36.680 回答