IssueRaiser

allow integer types to be any range

Zig already has ranged integer types, however the range is required to be a signed or unsigned power of 2. This proposal is for generalizing them further, to allow any arbitrary range. ```zig comptime { assert(i32 == @Int(-1 << 31, 1 << 31)); assert(u32 == @Int(0, 1 << 32)); assert(u0 == @Int(0, 1); assert(noreturn == @int(0, 0)); } ``` ---- Let's consider some reasons to do this: One common practice for C developers is to use `-1` or `MAX_UINT32` (and related) constants as an *in-bound* indicator of metadata. For example, the stage1 compiler uses a `size_t` field to indicate the ABI size of a type, but the value `SIZE_MAX` is used to indicate that the size is not yet computed. In Zig we want people to use [Optionals](https://ziglang.org/documentation/master/#Optionals) for this, but there's a catch: the in-bound special value uses less memory for the type. In Zig on 64-bit targets, `@sizeOf(usize) == 8` and `@sizeOf(?usize) == 16`. That's a huge cost to pay, for something that could take up 0 bits of information if you are willing to give up a single value inside the range of a `usize`. With ranged integers, this could be made type-safe: ```zig const AbiSize = @Int(0, (1 << usize.bit_count) - 1); const MyType = struct { abi_size: ?AbiSize, }; var my_type: MyType = undefined; test "catching a bug" { var other_thing: usize = 1234; my_type.abi_size = other_thing; // error: expected @Int(0, 18446744073709551615), found usize } ``` Now, not o

Posted by andrewrk on Nov 29, 2019, 10:31 PM

Tags

Related issues

Raise real-world problems, find people facing the same issue, and discuss solutions.3,500 issues0 comments

pricing (Software)

allow integer types to be any range

andrewrkNov 29, 2019, 10:31 PM

Zig already has ranged integer types, however the range is required to be a signed or unsigned power of 2. This proposal is for generalizing them further, to allow any arbitrary range. ```zig comptime { assert(i32 == @Int(-1 << 31, 1 << 31)); assert(u32 == @Int(0, 1 << 32)); assert(u0 == @Int(0, 1); assert(noreturn == @int(0, 0)); } ``` ---- Let's consider some reasons to do this: One common practice for C developers is to use `-1` or `MAX_UINT32` (and related) constants as an *in-bound* indicator of metadata. For example, the stage1 compiler uses a `size_t` field to indicate the ABI size of a type, but the value `SIZE_MAX` is used to indicate that the size is not yet computed. In Zig we want people to use [Optionals](https://ziglang.org/documentation/master/#Optionals) for this, but there's a catch: the in-bound special value uses less memory for the type. In Zig on 64-bit targets, `@sizeOf(usize) == 8` and `@sizeOf(?usize) == 16`. That's a huge cost to pay, for something that could take up 0 bits of information if you are willing to give up a single value inside the range of a `usize`. With ranged integers, this could be made type-safe: ```zig const AbiSize = @Int(0, (1 << usize.bit_count) - 1); const MyType = struct { abi_size: ?AbiSize, }; var my_type: MyType = undefined; test "catching a bug" { var other_thing: usize = 1234; my_type.abi_size = other_thing; // error: expected @Int(0, 18446744073709551615), found usize } ``` Now, not o

Comments (0)

No comments yet. Start the discussion.

Comment on this issue