On Wed, Sep 25, 2002 at 01:01:13AM +0900, William Djaja Tjokroaminata wrote:
> Regarding this, I am not so sure.  Under arbitrarily complex nested struct
> with a mix of VALUE's and ordinary C data, I think it will be a really
> hard work for the great-great-great-grandchildren on defining its mark and
> free functions for its class.  With the method that I proposed initially,
> I think an inheritance level can just define
> 
>     static void mark_me (sMyStruct* s)
>     {
>         /* mark my own VALUE's */
>         ....
>         /* mark my parent */
>         s->parentMarkFunc (s);
>     }

What I'm suggesting is something like this:

  /* We define a naming convention for a function func in class Klass:
   *   Klass_func
   * We also require that a class Klass with base class Base will have a
   * macro:
   *   Klass_Base
   * so at compile-time we can know who the base class is.
   */
  
  /* Some macros from the Boost preprocessor library */
  /* http://cvs.sf.net/cgi-bin/viewcvs.cgi/boost/boost/boost/preprocessor/cat.hpp */
  #define BOOST_PP_CAT(X,Y) BOOST_PP_CAT_DELAY(X,Y)
  #define BOOST_PP_CAT_DELAY(X,Y) BOOST_PP_DO_CAT(X,Y)
  #define BOOST_PP_DO_CAT(X,Y) X##Y
  
  #define BASE_OF(klass) klass##_Base
  #define CALL_BASE(klass, func) \
    BOOST_PP_CAT( \
        BOOST_PP_CAT(BASE_OF(klass), _), \
        func)
  #define CAST_TO_BASE(klass, x) \
    (BASE_OF(klass) *)(x)
  #define CALL_BASE_MARK(klass, x) \
    (CALL_BASE(klass, mark(((BASE_OF(klass) *)x))))
  
  typedef struct
  {
    /* ... */
  } Base;
  
  static void Base_mark(Base * b)
  {
    printf("Base_mark\n");
  }
  
  typedef struct
  {
    Base b;
  } Derived;
  #define Derived_Base Base
  
  static void Derived_mark(Derived * d)
  {
    printf("Derived_mark\n");
    CALL_BASE_MARK(Derived, d);
  };

The syntax isn't intuitive, but your mark function is looked up at
compile-time instead of at run-time.  If a small loss in maintainability
outweighs the speed gain, then you probably shouldn't use this trick.

Paul