2011-06-07 56 views
1

是不是故意,一個錯誤編碼延遲初始化:錯誤編碼延遲初始化工作得很好

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

不過確實「正確的事」,由於下面生成的代碼序列?

  • 裝載道具到RAX的測試
  • 歸國RAX在任何情況下
+0

我在代碼中看不到任何叫'rax'的東西。 – BoltClock 2011-06-07 09:16:34

+2

@Bolt'RAX'是一個x86_64寄存器。 – 2011-06-07 09:18:56

回答

4

這是不是故意的,而且即使它的工作原理,你不應該依賴於這一點。例如,考慮以下因素:

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

gcc -O0編譯:

movq -24(%rbp), %rdx 
movq [email protected](%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),但在第二次調用中崩潰。

+0

即使編譯器輸出對於這個特定的體系結構是100%可靠的,那麼誰又說你不需要爲另一個編譯器重新編譯呢? – walkytalky 2011-06-07 09:37:21

+2

@walky:可笑!蘋果不只是圍繞着交換架構!我的意思是真的!這都是PowerARMx868k,對嗎? – 2011-06-07 09:49:01

2

是故意,一個錯誤編碼延遲初始化:

你只是幸運,使用了標準的返回寄存器。永遠不要依賴它。實際上,它應該給你一個編譯器警告。