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.
精彩评论