On 16/09/2012 15:17, Nick Wellnhofer wrote:
Another solution is to provide the members pointer as an argument to every method:void Foo_set_num(Foo *self, Foo_MEMBERS *members, int num) { members->num = num; } The offset would then be applied in the method wrappers (Foo_Set_Num without the members argument). The same technique as in Marvin's initial approach could be used to store method and members offsets at a single memory location. This would give a slight performance benefit (mainly on x86, 32 bits) by avoiding a global variable lookup. But I'm not convinced it's worth the added complexity. I still prefer to make the lookup of the members struct explicit.
Thinking more about it, it's also possible to pass only member structs to methods if you add a pointer back to 'self' to every struct. Or you could use a pointer directly to the VTable. This is exactly what Marvin's initial approach does.
This leaves the problem of converting the members struct pointers from a source class to a target class for every method call. The obvious approach is to somehow work back to the start of the memory region of the object, and then apply an offset appropriate for the target class. Finding the the start of the object could be done by adding a field to every members struct. This would mean two additional fields if you want to keep direct vtable access (e.g. for method calls) from member structs. All of that looks rather expensive to me.
So in terms of what arguments a method could receive for the 'self' object, I can see the following solutions (in my order of preference):
1. Foo_set_num(Foo *self, int num) Cons: * One additional line of code per method for members lookup * One additional global variable access per method call for members lookup 2. Foo_set_num(Foo *self, Foo_MEMBERS *members, int num) Pros: * Lookup of members can probably be optimized slightly (at the expense of some VTable memory) Cons: * Additional method argument 3. Foo_set_num(Foo_MEMBERS *self, int num) Cons: * Memory overhead per members struct * Conversion of 'members' to another class for method calls is probably too expensive Nick
