8

I've read the question below, and the story SEEMS simple:

What exactly is super in Objective-C?

Yet ...

- (id) init
{
    NSLog(@"self=%p, super=%p", self, super);
}

That prints out "self=0xa83dc50, super=0xbfffe8d0". The addresses are NOT THE SAME???!?!?

That second address seems like a "special value" or something. What does it mean?

Thanks to bbum for pointing out that this value is the stack address of a special struct used by the compiler to implement the "super" behavior.


I can call [super init] and the call seems to work, or at least, nothing explodes ... not immediately. Calling [((id)0xbfffe8d0) init] fails hard with EXC_BAD_ACCESS.

Then there is the REALLY WEIRD part..... I've got a piece of code that for no explainable reason throws a "NSGenericException: collection was mutated while being enumerated" exception. Inside a DIFFERENT object (basically a wrapper that has a pointer to the NSEnumerator), commenting out the call to "[super init]" causes the exception to not happen. If I could, I'd put out a $$$ reward for an answer to THAT mind-bender.

"id sups = (id)0xbfffe8d0" ... that also leads to "collection is modified." ... WTF? Ok, so I'm posting a 2nd question for that bizzariotity ...


I originally came here with one of those "bizarre symtoms" bugs, that turned out to be entirely unrelated (typical for such things): Does casting an address to (id) have side-effects??? Is Address 0xbfffe8d0 special? (fixed: issue was with _NSCallStackArray)

However, the content above the line is still valid, and the response still excellent. Read it if you want to understand ObjC just a little bit deeper.

Community
  • 1
  • 1
Dave Dopson
  • 41,600
  • 19
  • 95
  • 85
  • 2
    Aside from your other issues, 0xbfffe8d0 is presumably a code address, but there's no reason to expect it would be the same from one compile to the next. Casting that literal value to a pointer is basically just creating a pointer from a random number. – Hot Licks Apr 01 '12 at 03:31
  • Actually, it's a stack address, which isn't the same thing as a code address. It's not even the same from one run to the next! – Dave Dopson Jul 16 '12 at 17:28
  • A stack address isn't even the same from one instant to the next in the same run. – Hot Licks Jul 16 '12 at 20:48

1 Answers1

16

You are messing with the man behind the curtain and he is punishing you for it... :)

super is a bit of compiler magic, really. When you say [super doSomething], the compiler will emit a call to objc_msgSendSuper() instead of objc_msgSend(). Most of the time -- there are some special cases.

In general, you should treat super as only a target for method calls. It should never be stored anywhere and should never be considered anything but that target expression for messaging.

In fact, uses of super that involve storage should likely be flagged by the compiler.

In terms of your bug, that sounds an awful lot like there is either corruption of memory, an over-release, and/or concurrency going on. You'll need to provide more code related to the enumeration and other relevant code to deduce further.

bbum
  • 162,346
  • 23
  • 271
  • 359
  • heh, "messing with the man behind the curtain" :) I posted a 2nd question with more details about that bug. – Dave Dopson Apr 01 '12 at 03:19
  • 6
    If you're interested, `super` is implemented (or used to be) as a pointer to a structure. The structure contained two elements, the first of which was `self`, and the second was the superclass, which tells the runtime which class to start looking in. – ughoavgfhw Apr 01 '12 at 05:33
  • AH! That explains the strange value. It's the stack address of that funky struct you mention. – Dave Dopson Apr 01 '12 at 18:26
  • 2
    Yup; if you were to look at the assembly, the compiler lays down said struct and then `objc_msgSendSuper()` uses the `isa` of the `superclass` to start the method search while using the struct's reference to `self` as the target of the method call. An implementation detail (thanks to @ughoavgfhw for going there!!). – bbum Apr 01 '12 at 20:51