« Snow Leopard: That's not my Unix anymore... | Main | va_list is now an array of some (opaque ?) struct... gee thanks »

The beginning of a bigger change ?

So I try to compile some older code (10.5) on SnowLeopard and I get:
error: @defs is not supported in new abi

The offending code looks something like this

@interface Foo
{
   void   *table1_;
}
@endif

static inline BOOL   Foo_IsASpecialObject( Foo *self, id p)
{
   return( NSHashGet( ((struct { @defs( Foo) } *) self)->table1_, p) != nil);
}
If you find this a little obscure, I once wrote an article about it (look for Using inline functions instead of method calls)

These are all the solutions to this particular problem I came up with:

  1. don't use the new ABI / abandon platform
  2. pester ABI maintainer to support @defs
  3. pester ABI maintainer to support static inline between @interface and @end
  4. painstakingly create a shadow struct, that mimics the Foo class
  5. unprotect inline accessed instance variables in Foo with @public
Just ignoring the ABI and sticking to 32 bit is a dead end on Mac OS X, so it's not an option. Option #2 and #3, well call me negative but I am also not buying lottery tickets because of the bad odds. Option #4 is extremely fragile, I don't want that. So for now I will have to make the instance variables @public. SIGH!

Comments (2)

#2 and #4 are simply not valid in the non-fragile runtime. Even if you have complete control of the class hierarchy, with a custom root class, the layout of your objects may change between system releases, or in principle, between runs of your app. You could use a dynamic ivar offset set in, say, +initialize, but then you’ve got to load a global each time the function is called.

#3 strikes me as reasonable, and filing a feature request won’t hurt. The ObjC guys aren’t entirely sealed within an ivory tower.

#5 is as clean as mucking about with objects using functions in the first place, so I don’t really see the problem. If you want it clean and encapsulated, use methods™.

Nat! Author Profile Page:

I think at some time I'd like to discuss the benefits of a non-fragile runtime, but that'd be lengthy and not for today.


As to point #5, I think it's actually worse, if I expose the instance variable via @public. With the function I remain in control. For example I can still be sure, that a dependent variable is also updated.

Or in bigger words using @public adds more to the complexity of the code than using @defs.

I am experimenting with a scheme like this at the moment (when the inline functions are used internally only), where I set FOO_IVAR_VISIBILITY to @public at opportune moments...

@interface Foo : NSObject
{
#ifdef FOO_IVAR_VISIBILITY
FOO_IVAR_VISIBILITY
#endif


It don't really like it, though the inline functions code is now much simpler.

Post a comment

(If you haven't left a comment here before, you may need to be approved by the site owner before your comment will appear. Until then, it won't appear on the entry. Thanks for waiting.)

About

This page contains a single entry from the blog posted on November 13, 2009 9:12 PM.

The previous post in this blog was Snow Leopard: That's not my Unix anymore....

The next post in this blog is va_list is now an array of some (opaque ?) struct... gee thanks.

Many more can be found on the main index page or by looking through the archives.

Powered by
Movable Type 4.25