Nat! bio photo

Nat!

Senior Mull.

Twitter RSS

Github

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!


2 Comments

A photo of Ahruman

From: Ahruman

#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™.

A photo of Nat!

From: Nat!

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

All comments are held for moderation; basic HTML formatting accepted.

Name:
E-mail: (not published)
Website: