This is the mail archive of the
guile@sourceware.cygnus.com
mailing list for the Guile project.
Re: So far, so good.
Dirk Herrmann <dirk@ida.ing.tu-bs.de> writes:
> > > To solve the 'SCM value as case label' problem, it would be necessary to
> > > provide a corresponding raw (i. e. unpacked) value for each SCM
> > > value. This could look as follows:
Without actually taking a closer look at any of these instances, I
wonder if converting to a sequence of 'if' tests would present much
difficulty? One thing I've been doing with guile-emacs has been
converting from:
switch (foo) {
case This:
...
case That:
...
}
to
if (EQ (foo, This)) {
...
} else if (EQ (foo, That)) {
...
} ...
which, if the compiler is doing its job, should have roughly the same
performance in the case where the tests still boil down to testing a
field against a constant. Even if they don't generate the same code,
the relative performance of the switch versus if-sequence is going to
be compiler- and usage-dependent anyways.
And when it's not a simple constant comparison, the second form is
still correct, while the first is not.
But my main reason for doing this is different from your situation:
I've been replacing enumerators with values assigned by smob type
number allocation, so the switch statement cannot work.
> typedef union { struct { scm_bits_t n; } n; } SCM;
> static SCM scm_pack(scm_bits_t b) { SCM s; s.n.n = b; return s; }
> #define SCM_UNPACK(x) ((x).n.n)
> #define SCM_PACK(x) (scm_pack ((scm_bits_t) (x)))
>
> Thus, SCM_BOOL_T is a result of a call to scm_pack. The compiler will not
> accept the result of a function call as a case label or as an
> initializer. Simply doing an unpack is from the compilers point of view
> no help, since the compiler will still not be able to determine the
> corresponding constant value: The compiler does not 'inline' and resolve
> the code for scm_pack.
#if __GNUC__ >= 2
#define scm_pack(b) ({ scm_bits_t __b = (b); SCM __s; __s.n.n = __b; __s; })
#endif
> Maybe somebody can think of a way to change the definitions for SCM_PACK
> and SCM_UNPACK, which will keep the same degree of type safety, but I
> doubt it: As long as we use a union or a struct for SCM values, the
> compiler would at least have to accept an expression like
> case (s.n.n = <some constant>, s.n.n):
> as a valid case label. I just checked: gcc does not accept it.
Yeah, that's a problem. Aggregate element extraction isn't an
operation that can yield a constant.