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]

Re: guile bugs


Martin Baulig <martin@home-of-linux.org> writes:
> Greg Badros <gjb@cs.washington.edu> writes:
> > 2) SCM should not be a long, but instead be a pointer to undefined
> > struct as we discussed before.  This would prevent misuse of an integer
> > as a Scheme value.
> How well does this behave on systems which align all pointers on word
> boundaries; I mean I'm a bit worried that not every integer number may also
> be a valid pointer on every system; even if you don't attempt to dereference
> that pointer.

I've seen cases where gcc (some old version, probably somewhere around
3-6 years ago) would shortcut tests like "(int)longptr & 3" and always
give 0, because, after all, any pointer to long on architecture X that
a program could get without running into "implementation defined"
behavior would have to be properly aligned.  (Or, maybe, you can get
the pointer but *using* it gives implementation-defined behavior.)

As far as I can tell, that's valid (since by strict interpretation the
code in question probably either is invalid or has "implementation
defined" behavior).  If it is, it's probably valid also for structure
pointers if a platform's ABI specifies that all structures are aligned
on N-byte boundaries, for N > 1.  The version of gcc I just tried
something similar with (gcc 2.95 on sparc-solaris) didn't make this
optimization, but it doesn't seem wise to me to rely on the compiler
*not* doing this (and on the user not having the old version where I
ran into this before).


I think the idea of making SCM a struct or union makes more sense.
Sucks for performance, though.  Well, in the normal case.  Do you mind
having the type checking be dependent on gcc?

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

A SCM object would get passed as a long, always.  Under gcc, using it
as a numeric value will not work.  This only works with recent enough
versions of gcc, of course, but transparent_union has been in there
for quite a while.  And for people with ancient versions of gcc, or
without gcc, they just don't get the type checking; they still get the
same calling convention, so even mixing gcc- and non-gcc-compiled code
works fine.

And if you still want type checking with non-gcc compilers, you can
still use the ordinary struct/union with lousy performance and
incompatible calling conventions, enabled through some special macro.

Normally I'm opposed to compiler-specific hacks in code, but if the
compiler in question is gcc, and the hacks in question merely optimize
or do better error checking without really changing functionality, I
don't have much problem with it.

Ken

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