Это не преднамеренно, и даже если это работает, вы не должны полагаться на это.Например, рассмотрим следующее:
- (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
и код действительно работает, потому что, как вы заметили, ивар загружается в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
- ивар был загружен в RBX
.Этот код работает при первом вызове (тот, который лениво инициализирует ivar), но вылетает при втором вызове.