Re: gauche.bitvector bug with somewhat bigger vectors (2^31)

Jens Thiele <[email protected]> Fri, 08 May 2026 08:43:54 +0200
Newsgroups gmane.lisp.scheme.gauche
Message-ID <[email protected]>
Shiro Kawai <[email protected]> writes:

> It may be a simple overlook, or pretty old before we start using
> ScmSmallInt.  Anyway, I updated the code so that bit indexes are all
> ScmSmallInt.  This may require recompiling extensions if they use bits.h.

I wasn't sure about that one. Maybe you wanted to keep int on 32-bit
platforms? But everywhere else it already was ScmSmallInt and
make-bitvector used fixnum since at least 2022.
=> there already was the limit of 2^(32-3)-1 bits?

(the ufixnum is quite new?)

But I think you missed Scm_MakeBits and bitvector-length. After this
additional change:

==

diff --git a/src/bits.c b/src/bits.c
index 6d362a208..962bc21d8 100644
--- a/src/bits.c
+++ b/src/bits.c
@@ -40,7 +40,7 @@
  * Construct, copy, fill
  */
 
-ScmBits *Scm_MakeBits(int numbits)
+ScmBits *Scm_MakeBits(ScmSmallInt numbits)
 {
     size_t nw = SCM_BITS_NUM_WORDS(numbits);
     ScmBits *bits = SCM_NEW_ATOMIC_ARRAY(ScmBits, nw);
diff --git a/src/gauche/bits.h b/src/gauche/bits.h
index 4e18d0ba8..babc3381b 100644
--- a/src/gauche/bits.h
+++ b/src/gauche/bits.h
@@ -52,7 +52,7 @@
 typedef u_long ScmBits;
 
 /* Allocates and returns a bitmap that can hold NUMBITS.  Zero-cleared. */
-SCM_EXTERN ScmBits *Scm_MakeBits(int numbits);
+SCM_EXTERN ScmBits *Scm_MakeBits(ScmSmallInt numbits);
 
 #define SCM_BITS_NUM_WORDS(size) \
     (((size)+SCM_WORD_BITS-1)/SCM_WORD_BITS)
diff --git a/src/libvec.scm b/src/libvec.scm
index feb700810..6f9bca3b8 100644
--- a/src/libvec.scm
+++ b/src/libvec.scm
@@ -668,7 +668,7 @@
 ;;;
 
 (define-cproc bitvector? (obj) ::<boolean> SCM_BITVECTORP) ;SRFI-178
-(define-cproc bitvector-length (v::<bitvector>) ::<int>    ;SRFI-178
+(define-cproc bitvector-length (v::<bitvector>) ::<fixnum>    ;SRFI-178
   SCM_BITVECTOR_SIZE)
 
 (define-cproc bitvector-any-value? (v::<bitvector> bit

==

it seems to work:
gosh$ (sid-amd64-sbuild)karme@amalthea:/tmp/Gauche$ src/gosh -ftest -V
Gauche scheme shell, version 0.9.16_pre2 [utf-8,pthreads], x86_64-pc-linux-gnu
(version "0.9.16_pre2")
(command "gosh")
(scheme.id gauche)
(languages scheme r5rs r7rs)
(encodings utf-8)
(website "https://practical-scheme.net/gauche")
(build.platform "x86_64-pc-linux-gnu")
(build.configure)
(build.gosh-version "0.9.16_pre2")
(scheme.path "/tmp/Gauche/src/../lib" "/tmp/Gauche/src/../libsrc" "/tmp/Gauche/src/../src" "/usr/local/share/gauche-0.98/site/lib" "/usr/local/share/gauche-0.98/0.9.16_pre2/lib")
(threads pthreads)
(gauche.net.tls)
gosh$ (use gauche.bitvector)
gosh$ (define bv (make-bitvector (ash 1 31)))
bv
gosh$ (bitvector-length bv)
2147483648
gosh$ (~ bv (- 2147483648 1))
0
gosh$ (set! (~ bv (- 2147483648 1)) 1)
#<undef>
gosh$ (~ bv (- 2147483648 1))
1

after all those years, I still always get confused by the C integer
types/sizes. (especially that long on 64-bit windows is 32-bit and
64-bit everywhere else? ...) But if I understand correctly on 32-bit
systems and 64-bit windows the size limit for bitvectors is 2^(32-3)-1
and 2^(64-3)-1 everywhere else?

jens

PS:
I just saw that C23 introduced support for N-bit integers:
https://www.open-std.org/jtc1/sc22/wg14/www/docs/n2763.pdf
but using that for ScmSmallInt likely would cause more trouble, than it
would help?