开发者

Wrong coded lazy initialization works well

开发者 https://www.devze.com 2023-03-11 03:37 出处:网络
Is it intentionally that a mis-coded lazy init: -(X*开发者_如何学JAVA) prop { if (!prop) { prop = [[Prop alloc] init];

Is it intentionally that a mis-coded lazy init:

-(X*开发者_如何学JAVA) prop {
    if (!prop) {
        prop = [[Prop alloc] init];
        return prop;
    }
    // RETURN SHOULD BE HERE 
}

nevertheless does 'the right thing' due to the generated code sequence below?

  • loading prop into rax for the test
  • returning rax in any case


It is not intentional and, even if it works, you shouldn’t rely on that. For example, consider the following:

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

When compiled with 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

and the code indeed works because, as you’ve noticed, the ivar is loaded into RAX.

However, when compiled with 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

Oops, no return value in RAX — the ivar was loaded into RBX. This code works in the first call (the one that lazily initialises the ivar) but crashes in the second call.


is it intentionally, that a mis-coded lazy init:

No.

You're just lucky that the standard return register was used. Don't ever rely on it. In fact, it should give you a compiler warning.

0

精彩评论

暂无评论...
验证码 换一张
取 消