diff options
author | Andy Wingo <wingo@pobox.com> | 2011-09-15 12:28:03 -0700 |
---|---|---|
committer | Andy Wingo <wingo@pobox.com> | 2011-09-15 12:28:03 -0700 |
commit | 75917d62434b103a89fc65bde66a1a3e97b598a1 (patch) | |
tree | 2fe0985637a7e95708d2d9aa2097160432e100eb /libguile/tags.h | |
parent | 8b66aa8f5496a515ca133d6d2c37a06f6ec1720d (diff) | |
download | guile-75917d62434b103a89fc65bde66a1a3e97b598a1.tar.gz |
Revert "SCM is either a union or scm_t_bits"
This reverts commit 80125469ef95f6d8d46a26619fb2f85151f32719.
Conflicts:
libguile/__scm.h
Diffstat (limited to 'libguile/tags.h')
-rw-r--r-- | libguile/tags.h | 54 |
1 files changed, 37 insertions, 17 deletions
diff --git a/libguile/tags.h b/libguile/tags.h index c03f43dfe..35b5d17c2 100644 --- a/libguile/tags.h +++ b/libguile/tags.h @@ -61,6 +61,7 @@ /* For dealing with the bit level representation of scheme objects we define * scm_t_bits: */ + typedef scm_t_intptr scm_t_signed_bits; typedef scm_t_uintptr scm_t_bits; @@ -69,28 +70,47 @@ typedef scm_t_uintptr scm_t_bits; #define SCM_T_BITS_MAX SCM_T_UINTPTR_MAX -/* But as external interface, we pack the bits in a union. This makes - * the compiler treat SCM values as a disjoint type, allowing the - * detection of many common errors. +/* But as external interface, we define SCM, which may, according to the + * desired level of type checking, be defined in several ways: */ -union SCM -{ - scm_t_bits n; -}; +#if (SCM_DEBUG_TYPING_STRICTNESS == 2) +typedef union SCM { scm_t_bits n; } SCM; +# define SCM_UNPACK(x) ((x).n) +# define SCM_PACK(x) ((SCM) { (scm_t_bits) (x) }) +#elif (SCM_DEBUG_TYPING_STRICTNESS == 1) +/* This is the default, which provides an intermediate level of compile time + * type checking while still resulting in very efficient code. + */ + typedef struct scm_unused_struct { char scm_unused_field; } *SCM; + +/* + The 0?: constructions makes sure that the code is never executed, + and that there is no performance hit. However, the alternative is + compiled, and does generate a warning when used with the wrong + pointer type. + + The Tru64 and ia64-hp-hpux11.23 compilers fail on `case (0?0=0:x)' + statements, so for them type-checking is disabled. */ +#if defined __DECC || defined __HP_cc +# define SCM_UNPACK(x) ((scm_t_bits) (x)) +#else +# define SCM_UNPACK(x) ((scm_t_bits) (0? (*(SCM*)0=(x)): x)) +#endif -#ifndef SCM_USING_PREHISTORIC_COMPILER -/* With GCC at least, wrapping the bits in a union provides no - * performance penalty. +/* + There is no typechecking on SCM_PACK, since all kinds of types + (unsigned long, void*) go in SCM_PACK */ -typedef union SCM SCM; -#define SCM_UNPACK(x) ((x).n) -#define SCM_PACK(x) ((SCM) { (scm_t_bits) (x) }) +# define SCM_PACK(x) ((SCM) (x)) + #else -/* But we do provide an escape valve for less capable compilers. +/* This should be used as a fall back solution for machines on which casting + * to a pointer may lead to loss of bit information, e. g. in the three least + * significant bits. */ -typedef scm_t_bits SCM; -#define SCM_UNPACK(x) (x) -#define SCM_PACK(x) ((SCM) (x)) + typedef scm_t_bits SCM; +# define SCM_UNPACK(x) (x) +# define SCM_PACK(x) ((SCM) (x)) #endif |