Hi, I think the way Rust handles integral values is well designed, but I have some problems with usize
types, caused by them being variable size on different systems. The problem is that code written to work on 64 bit system may raise overflows on a 32 system if the programmer isn't extra careful in using usize
values. I'd like a way to face this problem in a more principled/automatic way. Below I explain the problem in more details and I propose one possible solution. My solution could be bad. Perhaps you can suggest better solutions.
In my code I put a const_assert
because it assumes size_of<usize>::() >= 4
. (I know usize could be 2 bytes only, but most times I am not going to target that). I write the code on a 64 bit system. The code contains probably 10_000 or more operations among two usize
arguments, like multiplications. I try to keep values inside such 64 bit usize
s below 32 bit, but sometimes by mistake I may end up having numbers larger than that in my usize
values. The program works (because those numbers are less than 64 bits) but they are bugs (and cause overflow panics) if I compile the code on a 32 bit in debug mode. I'd like to have a way to spot such mistakes on a 64 bit system, so my code is portable to 32 bit systems too. A solution is to use u32 and cast only at the last moment to usize, but this introduces a ton of casts in my code that I want to avoid (even if I use safe casts with a macro). In some cases I do this, because this is the right solution, but in several other cases I'd like to avoid all those casts.
One solution could be to add standard features like:
#![feature(debug_overflow_usize_past_u32_max)]
#![feature(debug_overflow_usize_past_u16_max)]
Using the first one the compiler keeps using usize
values as large as before (this means on my system usize
keeps being 8 bytes) but that first feature adds in debug builds overflow tests that disallow values past 32::MAX inside usize
values (even when usize
is 8 or more bytes long). This way if there's a mistake in my code, and a 64 bit usize
variable gets a 33 bit value, it panics at run-time and I can fix the bug. What do you think about my solution? (Perhaps the only/best solution is just to compile to a 32 bit target in debug mode, and fix the overflow bugs).