guile-devel
[Top][All Lists]
Advanced

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

Re: scm_bits_t / scm_ubits_t


From: Dirk Herrmann
Subject: Re: scm_bits_t / scm_ubits_t
Date: Fri, 1 Jun 2001 11:53:28 +0200 (MEST)

On Thu, 31 May 2001, Jacques A. Vidrine wrote:

> So that there would be a  signed integer type and an unsigned interger
> type with which you are guaranteed the following for any pointer `p':
> 
>    (void *)p == (void *)((intptr_t)p)
>    (void *)p == (void *)((uintptr_t)p)   

Thanks for this definition.  It makes sure that uintptr_t is the right
type for scm_t_bits, at least for now:  scm_t_bits is the unsigned integer
type that a memory cell is made of.  Since we need to store pointers in
memory cells, it is necessary that any pointer can be represented without
loss of information in a variable of scm_t_bits.

Please note that currently, guile also at some places uses void* to
communicate scm_t_bits values, thus we need a one-to-one correspondence
between those two types.  This, however, seems not to be guaranteed by
uintptr_t, but we will assume that it is true.

> > The
> > information I have (from the glibc docs) is that size_t can hold the
> > size of all objects that can be allocated by malloc (or some other
> > means).  In a segmented architecture, I could imagine that there is
> > more memory available in toto than the maximum size of any single
> > object.
> 
> Or even on a more sophisticated system, I could conceive a programming
> environment where  the typical split  between kernel and  user address
> space is visible.

We do have the following situation:  Strings are allocated with malloc, i.
e. their length obviously fits into size_t.  The same is true for ordinary
scheme vectors, but it is different for bit-vectors, since their maximum
length can exceed the maximum length of an allocated vector.  However, as
long as we store vector and string lengths in a single value of type
scm_t_bits, we should not have any problems.  It is a different thing with
lists, though:  Since lists can cross several chunks of allocated cells,
it is not necessarily true that a list length can be stored in variables
of type size_t.  Since list lengths are not stored in cells, we don't know
whether the maximum list length will fit into a variable of type
scm_t_bits.  But, since every cell has an associated memory address, i. e.
pointer, for list lengths a variable of uintptr_t should be OK.

Thus, for the current time we could define that:
* string lengths -> size_t
* vector lengths -> uintptr_t (actually, scm_t_bits, but I'd prefer not to
  use scm_t_bits for anything else than cell data)
* list lengths -> uintptr_t

Things could change if we one day decided for example to store vector
lengths across two cell elements.  Then, the maximum vector length would
oviously no longer fit into a variable of type scm_t_bits.  It therefore
may make sense to use typedefs scm_t_vector_length or scm_t_string_length
etc., but I am not sure we should do it...  It might end with having to
produce a large number of types, which are alike on all architectures that
guile runs on anyway.  And, since AFAIK compilers don't allow us to
distinguish between typedefs that are based on the same type, keeping type
strictness is difficult to maintain.

> [1] Ooh,  won't it be  nice when we  have C99 widely  available?  Then
>     scm2u?int and u?int2scm can work for all integer types!
> 
>     intmax_t  scm2int(SCM);
>     uintmax_t scm2uint(SCM);
>     SCM       int2scm(intmax_t);
>     SCM       uint2scm(uintmax_t);
> 
>     For u?int2scm,  the compiler  will take  care of  promoting types.
>     For scm2u?int,  the programmer just  compares the result  with tbe
>     appropriate constant.
> 
>       int intfunc(...) {
>           intmax_t n;
>           ...
>           n = scm2int(aNumber);
>           if (n < INT_MIN || n > INT_MAX) 
>                   boom();
>           else
>                   return n;
>       }
> 
>    Gee, I wonder if  we could do this now by  defining intmax_t and so
>    on  ourselves, or  by using  our own  typedef for  ``biggest native
>    integer''.

That's a good suggestion.

Best regards,
Dirk Herrmann




reply via email to

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