This is the mail archive of the guile@cygnus.com mailing list for the guile project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Re: Object type tag bits


On Wed, 28 Oct 1998, Frank Cieslok wrote:

> ...so I tried to create my own smobs using a C++ function like this :
[...]
> This function was registered via gh_new_procedure() and therefor callable 
> by guile code. The class 'Object' is keeping references to other scheme 
> objects and a mark function for garbage collection was needed to let these
> objects survive garbage collection, too :
> 
>    SCM mark(SCM s)
>    {
>        ...
>        SCM_ASSERT( (SCM_NIMP(s) && SCM_CAR(s) == ObjectTag),
>                    s, SCM_ARG1, "mark" );
>        ...
> 
>        return SCM_BOOL_F;
>    }
> 
> The assertion always falied, because the tags did not match. When 
> created by createInstance(), the new object got #x1EF7 as tag value, the 
> mark function was called with a parameter tagged with #x1EFF. The CDR of
> the smob was equal in both cases.
> 
> I did not completely understand the code in "libguile/tags.h". Is only a 
> part of the tag used for object type information ? If so, is there a 
> function returning just these valid bits for comparison with the tag 
> value returned by scm_newsmob() during object registration ?

Hi Frank!

As you guessed right, guile uses only parts of the tag for object type
information. Especially one bit has a different meaning: It is used during
garbage collection and tells the garbage collector 'don't delete me'.
As you can guess from the data you provided, it's bit 0x0008 (but this is
true for smobs only! Other types use different bits! Even in case of
smobs: don't rely on this fact!)

To make things easier for the programmer, guile sets this bit
automatically for you _before_ the mark function is called. This means,
the moment your mark function is called, the tag has been changed already. 

However, you don't need to perform that assertion anyway: your mark
function is guarantueed to be called only for the correct smob type. So
just remove the call SCM_ASSERT and everything should be fine.


If you definitely want to access the smob type during garbage collection,
which you (in my opinion) should avoid, then there is a very clean
solution to this problem:

Macro: void SCM_GCTYP16 (SCM x) 
       Return the type bits of the smob x, with the mark bit clear.

The beauty of this expression is far beyond those spheres we mortal
programmers are supposed to get in touch with :-)


Best regards, 
Dirk Herrmann