The problem is revealed: there is work to be done after the recursive call: automatic reference counting inserted a release call for the value returned from
node.next. If we were writing this with manual retain/release, one wouldn’t insert any memory management calls into this at all, because
-nextreturns an autoreleased object. However when this is compiled under ARC, calls to
objc_releaseare inserted to allow for another optimization — having the return value skip the autorelease pool entirely. Unfortunately in this case, it conflicts with tail call optimization.
In an ARC environment, tail call optimization (and thus tail recursion) is too fragile. Don’t rely on it.
Stay up-to-date by subscribing to the Comments RSS Feed for this post.