Short and sweet: Why does the following block of Objective-C code not produce a compiler error/warning?
- (void)someMethod:(MyObject *)someArg {
MyObject *t = [self otherMethod:t.property]; // Typo. 't.property' should be 'someArg.property'
[t doSomething];
}
I understand the runtime behavior, as 't' actually points to an invalid memory address when allocated.
Eg. the above line of code is logically equivalent to:
MyObject *t;
t = [self otherMethod:t.property];
[t doSomething];
In Java this (if I remember correctly) generally causes a compiler error, as the variable t is guaranteed to have no valid value when the property
getter is called. (Sure, it has a value, but it's not one worth having.)
I ran into this issue a few minutes ago and it took me longer than I would have liked to determine what the problem was. Why does the compiler not warn (in either code snippet) that the pointer t
is being used before it has properly been initialized?
Because the objective-c compiler is not related to the Java compiler, so there's no reason for it to handle the same error case the same way that the Java compiler would.
I agree it would be better if the compiler did at least raise a warning in cases like this, but in a language that allows direct manipulation of pointers it's really hard to reliably detect this case. For instance:
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];