On 5 Mar 2009, at 16:10, Gregory Casamento wrote:
The last collective release was only two months ago.
As far as the ABI is concerned that is certainly an issue. The
last time we discussed it we came up with two solutions:
• Pad the ivar-structures in the classes out to give space to grow
so that it pushes off any ABI compatibility issues as long as
possible. This is why in some APIs, including Cocoa, you see
things like "reserved..." or "private..." variables. These are
there to give room to grow. The disadvantage is that the classes
would then take up more memory as a result.
And oftentimes the padding is insufficient for what you want to do.
So this mechanism alone can't make the code future-proof.
• Move the ivar-structures out of the classes and replace them with
a void pointer to the actual structure. This has the advantage
that we will never be able to break ABI compatibilty since the sizes
of the structs in the classes will not change... but it also has the
disadvantage of adding a layer of complexity to getting and setting
variables
True. The code complexity is easily overcome by using the C
preprocessor, but it's a real pain trying to examine such classes from
within gdb.
as well as potentially causing unpredictable issues due to unforseen
incompatibilities such as cases where the wrong data is written into
a data structure causing some sort of corruption when using the
wrong version of a library.
That can't happen ... if you are using a different version of the
library then it's using its own different version of the data structure.
The big disadvantage of this approach is (in some cases) performance.
You have to do twice as much memory allocation/deallocation sincethe
object and the structure holding its ivars are separate. This is
really bad news for objects which are created/destroyed frequently,
but irrelevant for other objects with long lifetimes.
I, personally, think we should implement the first option. It's the
method most APIs follow and it is the method that is the most
predictable. It would take some effort to do this, but it's minimal
since it's really just padding the structures with a given amount of
space.
You missed one of the most common strategies used in Cocoa ...
declaring the public API as an abstract base class with no instance
variables, and returning instances of privates subclasses. I dislike
that as it makes it impossible to properly subclass many classes, but
as we are aiming for Apple compatibility it's not really a
disadvantege (people can't subclass easily in Cocoa either).
Where apple use class clusters, we may as well do the same thing.
Otherwise, where we are adding new classes we should probably use a
pointer to private data for long lived and complex classes with a lot
of instance variables, but use padding (reserve a pointer too as part
of the padding) for simpler classes with a short lifetime.
With the void* pointer to the structure we might be able to do
something clever to help debugging. I haven't tried it, but we could
define a preprocessor symbol (eg. GSRESERVED) which normally expands
to 'void*' (in the public API) but expands to 'struct foo*' inside the
source files, so that the symbol tables in the compiled code know
what the internal variable layout actually is, and gdb can therefore
make sense of things when examining the an object.
_______________________________________________
Gnustep-dev mailing list
Gnustep-dev@gnu.org
http://lists.gnu.org/mailman/listinfo/gnustep-dev