guile-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

equal? and smob flags


From: Andreas Vögele
Subject: equal? and smob flags
Date: Mon, 6 Sep 2004 09:52:55 +0200

When comparing smobs of the same type but with different smob flags the procedure scm_equal_p in eq.c returns #f since the cell types, which include the smob flags, are not equal.

I'm wondering if this behaviour is really intended. IMHO it would be more useful to ignore the flags in scm_equal_p when comparing smobs. Instead developers could decide on their own whether to ignore or consider the smob flags in their custom comparison function.

The macros SCM_CELL_TYPE and SCM_SMOB_FLAGS are defined in gc.h and smob.h respectively:

#define SCM_CELL_TYPE(x) SCM_CELL_WORD_0 (x)

#define SCM_SMOB_FLAGS(SCM_CELL_WORD_0 (x) >> 16)

The comparison of smobs with different flags fails because of the following conditional in scm_equal_p:

if (SCM_CELL_TYPE (x) != SCM_CELL_TYPE (y))
  {
    ...
    return SCM_BOOL_F;
  }

I don't know if there's existing third-party code that relies on the fact that the smob flags aren't ignored by scm_equal_p. But if such code existed it code could be updated easily by adding two lines of code to the comparison function:

SCM_SMOB_EQUALP (my_tag, my_equalp, x ,y)
{
  if (SCM_SMOB_FLAGS (x) != SCM_SMOB_FLAGS (y))
    return SCM_BOOL_F;
  /* Existing code follows here */
  ...
}

I've included a patch that changes scm_equal_p so that smobs that provide their own comparison function are compared before the cell type is compared:

Index: libguile/eq.c
===================================================================
RCS file: /cvsroot/guile/guile/guile-core/libguile/eq.c,v
retrieving revision 1.51
diff -u -r1.51 eq.c
--- libguile/eq.c       17 Aug 2004 23:19:04 -0000      1.51
+++ libguile/eq.c       6 Sep 2004 07:03:46 -0000
@@ -157,6 +157,15 @@
     }
   if (SCM_TYP7 (x) == scm_tc7_string && SCM_TYP7 (y) == scm_tc7_string)
     return scm_string_equal_p (x, y);
+  if (SCM_TYP7 (x) == scm_tc7_smob && SCM_TYP7 (y) == scm_tc7_smob
+      && SCM_SMOBNUM (x) == SCM_SMOBNUM (y))
+    {
+      int i = SCM_SMOBNUM (x);
+      if (!(i < scm_numsmob))
+       return SCM_BOOL_F;
+      if (scm_smobs[i].equalp)
+       return (scm_smobs[i].equalp) (x, y);
+    }
   /* This ensures that types and scm_length are the same.  */
   if (SCM_CELL_TYPE (x) != SCM_CELL_TYPE (y))
     {
@@ -194,16 +203,6 @@
     case scm_tc7_vector:
     case scm_tc7_wvect:
       return scm_vector_equal_p (x, y);
-    case scm_tc7_smob:
-      {
-       int i = SCM_SMOBNUM (x);
-       if (!(i < scm_numsmob))
-         return SCM_BOOL_F;
-       if (scm_smobs[i].equalp)
-         return (scm_smobs[i].equalp) (x, y);
-       else
-         break;
-      }
 #if SCM_HAVE_ARRAYS
     case scm_tc7_bvect: case scm_tc7_uvect: case scm_tc7_ivect:
     case scm_tc7_fvect:        case scm_tc7_cvect: case scm_tc7_dvect:





reply via email to

[Prev in Thread] Current Thread [Next in Thread]