Reputation: 317
I have 2 classes A and B,B is inherited from A,A is inherited from NSObject.Class A has a function -(void)init:
- (void)init {
if (self = [super init]) {
NSLog(@"A");
}
return self;
}
B has:
- (id)init {
if (self = [super init]) {
NSLog(@"B");
}
return self;
}
After compilation I have "A" and "B" in my console,despite of condition in B "if (self = [super init])" can't be true,cause its superclass init method returns void.Any ideas?
P.S. I know that init method must return id,I'm interested why this works while it shouldn't.
Upvotes: 3
Views: 868
Reputation: 237110
You're invoking undefined behavior by assigning the result of a void function call. Undefined behavior means pretty much anything can happen. This falls under the header of "anything," so it can happen.
As for why the compiler isn't noticing your mistake: You probably neglected to declare the override in your header, so it's assuming that your method has the same signature as the nearest declaration it can find, NSObject's.
Upvotes: 5
Reputation: 16149
Listen to Chuck. He's smart :)
I'll try to add a bit more detail.
One way to think about this is "If both were declared -(id)init
how would A return its value to B"?
It goes something like this. The return self
statement would take the pointer to A and put it in an agreed upon location. This location would be defined in the ABI. On a OSX/x86-64 machine, it's the RAX register (IIRC). So return self
really says "write the pointer to self into RAX".
Then when B regains control it knows the return value is in RAX and can use it however it likes. Note you didn't remove the return self
statement from A's implementation, so self was probably still written to RAX where B found it and used it. Or maybe RAX still had a pointer from the NSObject init
implementation. You'd have to disassemble it to know for sure.
Now let's say you didn't keep the return self
in A's implementation. Now there's some random junk in RAX which B is going to try to use like it's a pointer to an A. This is where the undefined behavior Chuck mentions comes in. If you're lucky it will just crash.
I'm guessing your code above gave some compiler error/warning that you had to suppress?
Upvotes: 5