
Issue #20614 has been updated by alanwu (Alan Wu). I [tried] making it return 8 for fixnums on Windows and that revealed a bunch of false assumptions `ruby/spec` makes. It has code like `def max_long = 2**(0.size * 8 - 1) - 1` and assumptions about `sizeof(long) == sizeof(void*)` sprinkled around (e.g. tests for `Array#pack` and friends). If we change it to return 8 on Windows with no other changes, we expose people making (false) assumptions to a few issues: getting fixnum bounds from `0.size` by assuming that most of the bytes are used; getting `long` related bounds from `0.size` by assuming the implementation will never change; assuming `0.size` has some relationship with the size of data pointers. The most prominent gem that makes false assumptions is `concurrent-ruby`. (Thanks for the code search ko1!) These are definitely user errors, but we should try and minimize breakage when making changes regardless. People can avoid all of these issues by using `RbConfig::{LIMITS,SIZEOF}` from `rbconfig/sizeof`, but that's undocumented in all releases; I added docs recently. We can fix the weirdness of having unused bytes in fixnums on LP32 platforms like Windows by defining fixnums based on VALUE. That's good for everyone and probably a better time to change what `0.size` returns. [tried]: https://github.com/ruby/ruby/pull/11130/commits ---------------------------------------- Bug #20614: Integer#size returns incorrect values on 64-bit Windows https://bugs.ruby-lang.org/issues/20614#change-109190 * Author: surusek (Ćukasz Sur) * Status: Rejected * ruby -v: ruby 3.4.0dev (2024-07-08T11:00:01Z master 02c4f0c89d [x64-mswin64_140] * Backport: 3.1: UNKNOWN, 3.2: UNKNOWN, 3.3: UNKNOWN ---------------------------------------- According to the ruby/spec, `0.size` should return size of the machine word in bytes, but on x64-mswin64_140 (both release 3.3.3 and git revision 02c4f0c89d) it doesn't. Following example: ``` ruby a, b = 0.size, [0].pack('J').length puts a, b ``` should print two `8`s, but on x64-mswin64_140, a is `4`. Issue is most likely caused by use of `long` instead of `SIGNED_VALUE` in internal/fixnum.h and `fix_size` function in numeric.c, because on Windows, `long` is always a 32-bit number. -- https://bugs.ruby-lang.org/