Would having both `iptr/uptr` and `idiff/usize` in Rust be a good idea? (Answer: No.)


#1

The discussions in RFC PR 544 leads me to think that, if we cannot find a single pair of names for pointer-sized integer types that can satisfy most people, would having two pairs for different use cases be a good solution?

The core problem with the proposed names is that, pointer-sized integers have many different use cases in Rust, but barring one (imem/umem, and the variant intm/uintm), all candidate names are either too vague, or favouring specific use cases over others, and/or looking like some C/C++ types that may tempt people to make incorrect assumptions. And imem/umem are not liked enough either.

So maybe we can take a page out of standard C/C++'s book, and define both iptr/uptr and idiff/usize, and use them in different use cases?

iptr/uptr will be used in cases where intptr_t/uintptr_t get used in C/C++: for storing casted pointer values.

And idiff/usize will be used like ptrdiff_t/size_t: pointer/index offsets and container sizes/indices, respectively.

iptr/uptr will be the underlying types, and idiff/usize will either be their aliases, or considered different types (“newtypes”) entirely. (In the latter case, the fact that idiff/usize are pointer-sized may or may not be considered an implementation detail.)

This setup will make Rust’s integer types align well with standard C’s, which is a plus from the familarity point of view. Still, the underlying sementics is not completely the same, and having two pairs of types that share the same underlying representation may be confusing, but these drawbacks are smaller in my eyes than using uptr for container sizes or usize for storing pointer values.

(I personally still prefer the imem/umem solution to this, but I can see why many others don’t agree with me. This solution is my second favourite now.)

So, is iptr/uptr/idiff/usize a good idea or will it create much unnecessary confusion?

(Here are the thanks to @theme who pointed me to ptrdiff_t and helped me realize that ssize_t is not in the C standard and not for offsets, and isize/usize should rather be idiff/usize.)


#2

Having multiple int replacements is a ingesting idea if…

  1. …they have different types (not aliases)
  2. … they are simply convertable

This would prevent some logical bugs like indexing a array with an pointer (in a ffi). A possible set of types would be uptr, usize, uindex, idiff, pint, puint or similar (pint =platform dependent int), also not that there is no iptr because there is no negative pointer.

Neverless I am not sure if this is a good idea. Having multiple platform dependent int/uint types might be confusing for beginners and might introduced a lot of unessesary (hopefully zero overhead) conversations.

So or so from my opinion there should be a int type witch name says that it is platform dependent and nothing more like the suggested intx/uintx, into/uintp, pint/puint or similar (just int/uint would fell like the default int type and is therefore not a good idea).

Thinking about it more having at last a index int type to show that (array) indexing should be done with a platform specific int (*) and maybe a uptr for FFI functions witch have to handle intifyed pointers would be really nice for speaking programming.

(* I an not completely sure but it would reduce the risk of indexing with u32 a array witch size extends the u32 range. Also not that indexing with u64 might be ok on 64bit systems but not the best idea on 32bit systems, especially if there is some arithmetic to calculate the index)


#3

I am increasingly unsatisfied with this (or any other alternative that involves C-like type names) because of the semantics difference between C and Rust. imem/umem should be the way to go.


#4

The problem is that subtracting two iptr/uptr's should give an idiff (at least if they do what their name suggest), and increases the number of rules rust users have to remember.

Additionally, if you want a pointer, would you use iptr or uptr? I don’t know


#5

@theme, yes, and actually if we completely confirm to the C standard, the only operations that are guaranteed to work correctly on iptr/uptr (or intptr_t/uintptr_t) should be the conversion to and from a pointer. But Rust’s int/uint have stronger guarantees, and don’t completely confirm to any of the C types’ semantics or conventions. So I now agree this iptr/uptr/idiff/usize solution would add confusion and hide the actual semantics of int/uint for questionable gain.

We should use imem/umem.