This is the mail archive of the guile@sourceware.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]

Summary and patch template: compile time debug mode


Hello guilers.

I know it's a sad time now that two of guile's major contributors quit.
Thanks to both of you giving much work as a gift to the guile and scheme
community.

Thus, I do not really know who might want to discuss this topic, and, who
might be the one who would do a checkin in case we can come to an
agreement.  However, here we go:


It seems to be agreed that we need some kind of distinction for how to
define SCM.  According to Ken Raeburn, gcc will once be able to support
transparent unions that can be handled as efficiently as long values.
Thus, we might as one option define SCM as:

    typedef union { long n; } __attribute__ ((transparent_union)) SCM;

While this provides us with a maximum of type safety, it requires to write
x.n to access the actual content of a SCM variable.  

However, for older versions of gcc this definition would lead to
performance loss and for non-gcc compilers it can not be used at all.

For non-gcc compilers we still could use a union for SCM, like in the
following definition:

    typedef union { long n; } SCM;

Again: maximum type safety and the need to access the contents via x.n

But this will also cause a performance loss.  Thus, to avoid this, we will
have to provide some definition of SCM that allows for the best
performance on the corresponding architecture.  This may be for example

    typedef struct { <something> } *SCM;

or

    typedef long SCM;

with the former providing at least some kind of type safety, while still
leading to problems with expressions of the kind

    SCM x;

    ...
    if (x) ...  // no compile time error, even if SCM is a pointer.
                // But:  compile time error if SCM is a union.

Thus we have two options:

a) choose the union kind of definition for SCM:
   + maximum type safety
   + maximum performance on some future versions of gcc
   - performance loss in most (all?) other cases
b) choose the long/pointer kind of definition for SCM:
   + optimum performance in all cases
   - not so good / bad type safety


It seems to be agreed that we have to provide the definition with the best
performance.  Thus, we will have to provide at least one definition for SCM
of type b).  But, as soon as gcc will support efficient transparent
unions, we would like to make use of style a) also.

Consequently, we will have two different definitions for SCM:  One using
the union kind, one using the long/pointer kind.  Both definitions require
different ways of accessing the content of a SCM variable:
    (x.n)          union
    ((long)(x))    pointer
    (x)            long
To make this transparent throughout guile we will have to use a macro to
access the content of a SCM variable.


The remaining problem is, that for compilers other than the future gcc, we
will not be able to make use of optimum type checking without performance
loss.  However the following solution would solve this problem at the cost of
an additional compilation run for developers who want to test type safety (the
code is from Ken Raeburn, extended by the part with the compile time debug
mode):

Change the definition of SCM in tags.h to

#if __GNUC__ >= 2 && __GNUC_MINOR__ >= whatever...
    typedef union { long n; } __attribute__ ((transparent_union)) SCM;
    #define SCM_CONTENT(X) ((X).n)
#else
  #ifdef GUILE_TYPE_SAFETY_CHECKING_MODE
    typedef union { long n; } SCM;
    #define SCM_CONTENT(X) ((X).n)
  #else
    typedef long SCM;
    #define SCM_CONTENT(X) (X)
  #endif
#endif

Then, a developer who wants to check the type safety of some file f.c first
compiles this file with the macro GUILE_TYPE_SAFETY_CHECKING_MODE defined,
throws away the object file and (after all type errors have been fixed)
compiles it again without the macro GUILE_TYPE_SAFETY_CHECKING_MODE defined.

The nice thing about this is, that by applying the patch guile will still be
able to compile and we will still be able to link to existing libraries.
However, by setting GUILE_TYPE_SAFETY_CHECKING_MODE to true, we will be able to
start looking for places in guile where the SCM_CONTENT macro has to be used.
But as soon as GUILE_TYPE_SAFETY_CHECKING_MODE is undefined again, everything
works as before.

Thus, guile can be smoothly brought up to a state where the union kind of
definition for SCM will be working.  As soon as guile for itself can be
compiled with the GUILE_TYPE_SAFETY_CHECKING_MODE macro defined, the above code
can be replaced by

#if __GNUC__ >= 2 && __GNUC_MINOR__ >= whatever...
    typedef union { long n; } __attribute__ ((transparent_union)) SCM;
    #define SCM_CONTENT(X) ((X).n)
#else
  #ifdef GUILE_TYPE_SAFETY_CHECKING_MODE
    typedef union { long n; } SCM;
    #define SCM_CONTENT(X) ((X).n)
  #else
    typedef struct { <something> } *SCM;
    #define SCM_CONTENT(X) ((long)(X))
  #endif
#endif

without causing any harm.  This will then provide some more type safety for
non-gcc/old gcc compilers, even without GUILE_TYPE_SAFETY_CHECKING_MODE
defined.  However, on these compilers the full type safety checks will only be
performed with the GUILE_TYPE_SAFETY_CHECKING_MODE macro defined.

I hope all of you agree that this is a good solution.

I suggest the name SCM_CONTENT, because it is not used yet within guile and it
is not a prefix for any other identifier used within guile.  Thus, it can
easily be searched for.  Also, it is descriptive.  Maybe some native english
speakers have a better idea, but I think it might be a good choice.  Since it
can be easily searched/replaced we can easily change it later if we once feel there is a more appropriate name.

Further, I suggest the name GUILE_TYPE_SAFETY_CHECKING_MODE because it is
descriptive and since it is so long, nobody would enable it by coincidence.
Again, better ideas welcome.  However, the name of this macro only appears at
a single point within guile (and maybe later in some developer's makefiles),
so the choice of this name is not very important.


Please comment, and if a general agreement can be achieved, please apply the
corresponding patches.  I would be willing to write up some documentation /
comments in tags.h or the manual.


Best regards,
Dirk Herrmann


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