2011-03-20 74 views
1

簡而言之:爲什麼下面的Objective-C代碼塊不會產生編譯器錯誤/警告?在定義相同的語句中使用變量?

- (void)someMethod:(MyObject *)someArg { 
    MyObject *t = [self otherMethod:t.property]; // Typo. 't.property' should be 'someArg.property' 
    [t doSomething]; 
} 

我明白了運行時的行爲,爲「t」分配時實際指向一個無效的內存地址。

例如,上面的代碼線是邏輯上等同於:

MyObject *t; 
t = [self otherMethod:t.property]; 
[t doSomething]; 

在Java這(如果我沒有記錯)通常會導致編譯器錯誤,因爲變量t保證沒有有效值時property吸氣劑被調用。 (當然,它的值,但它不值得擁有。)

我在幾分鐘前遇到了這個問題,花了比我想要的更長的時間來確定問題所在。爲什麼編譯器不會警告(在任一代碼片段中)指針t在被正確初始化之前正在使用?

+0

Sun的javac編譯器會錯誤的,是的(我想這是有可能找到/創建一個編譯器,這將允許未定義行爲出現,儘管JVM的基於堆棧的字節代碼和Java規範將使那是不太可能的 - 更不用說越野車了;-)。 – 2011-03-20 04:53:02

+0

是的,我很確定這會被Sun的編譯器拒絕。我覺得奇怪的是,在LLVM GCC 4.2中這不是一個錯誤,特別是考慮到它是一個局部變量。 – 2011-03-20 04:58:42

回答

2

由於objective-c編譯器與Java編譯器無關,所以沒有理由像Java編譯器一樣處理相同的錯誤情況。

我同意,如果編譯器在這種情況下至少發出警告,但是在允許直接操作指針的語言中很難可靠地檢測到這種情況,那會更好。例如:

MyObject* t; 
MyObject** pointerToT = &t; 
*pointerToT = [[MyObject alloc] init]; 

//now I can use 't', even though I never assigned anything to it directly 
[t doSomething]; 
+0

感謝您的示例 - 這是編譯器不顯示警告/錯誤的好原因。 – 2011-03-20 14:37:25