# If \`int\` has the wrong size ...?

**URL:** <https://internals.rust-lang.org/t/if-int-has-the-wrong-size/454>\
**Category:** bikeshed (deprecated)\
**Created:** [September 2, 2014, 10:37pm UTC](https://internals.rust-lang.org/t/if-int-has-the-wrong-size/454 "2014-09-02T22:37:16Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![pnkfelix](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/pnkfelix/32/110_2.png) [@pnkfelix](https://internals.rust-lang.org/u/pnkfelix)\
**Post date:** [September 2, 2014, 10:37pm UTC](https://internals.rust-lang.org/t/if-int-has-the-wrong-size/454/1 "2014-09-02T22:37:16Z")

</div>

@steveklabnik posed the question: What should we be suggesting at the type to use by default in the Guide for integrer valued things ([Rust Issue #15526](https://github.com/rust-lang/rust/issues/15526)).

Meanwhile, in the discussion about putting integer fallback [RFC PR 212](https://github.com/rust-lang/rfcs/pull/212) back in, part of the argument during the [team meeting](https://etherpad.mozilla.org/ep/pad/view/Rust-meeting-weekly/L01uph7odA) for why we need a by-default fallback (as opposed to one you opt into via a scoped attribute) was that `int`, as in the type named “int” (whatever that may be), will be the type that people expect as the default, ending with: “if `int` has the wrong size [then] that’s a different discussion.”

So, okay, let us have that discussion somewhere then. Maybe on this discuss thread. 🙂

* * *

The fact that the integer arithmetic type that most everyone will reach for at first (`int`) is the one that is inherently platform dependent _is_ troubling to me.

Note that this is distinct from concerns about the presence of a fallback. I actually do find the “Lack of bugs” argument from [RFC PR 212](https://github.com/nikomatsakis/rfcs/blob/restore-int-fallback/active/0000-restore-int-fallback.md#lack-of-bugs) persuasive. But that is only dicussing the cases where no type annotation nor `i32`/`i64` suffix is provided; it says nothing about the cases where the user _wrote_ `int` even though it is actually inappropriate to their problem domain.

* * *

[Rust Issue #9940](https://github.com/rust-lang/rust/issues/9940) was one take (with a very long attached discussion) on how to address this problem. Well, sort of: namely by renaming `int`/`uint` to something that made it clear that they are pointer-sized (and thus really only for use as indexes into objects in the address space). That RFC suggested `intptr_t` / `uintptr_t`

- Anyway, #9940 got closed because the person who filed the issue didn’t think the change was worth the trouble anymore.

You can read the arguments back-and-forth on the comment thread for [#9940](https://github.com/rust-lang/rust/issues/9940) and for [RFC PR 212](https://github.com/rust-lang/rfcs/pull/212) about what the size of a default type should be (i.e. some people thought it should be fast, i.e. [`i32`](https://github.com/rust-lang/rfcs/pull/212#issuecomment-53532124), others thought we should discuss something less likely to under- or overflow, namely [`i64`](https://github.com/rust-lang/rfcs/pull/212#issuecomment-53495467)).

I am sympathetic to both arguments; I wanted us to consider `i64` as a default size, but I would not fight `i32` if my only alternative is the platform-dependent size aka `intptr_t`.

In any case, renaming the current `int` to `intptr_t` is probably not enough on its own, because I suspect the type names `int` and `uint` (and likewise the suffixes `i` and `u`) are too sweet to give up. So then, what do we use them for?

(See also related topic: [Integer Types](http://discuss.rust-lang.org/t/integer-types/470) )

---

<div class="post-metadata">

**Author:** ![pnkfelix](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/pnkfelix/32/110_2.png) [@pnkfelix](https://internals.rust-lang.org/u/pnkfelix)\
**Post date:** [September 2, 2014, 10:45pm UTC](https://internals.rust-lang.org/t/if-int-has-the-wrong-size/454/2 "2014-09-02T22:45:36Z")

</div>

There is also [Rust Issue #16446](https://github.com/rust-lang/rust/issues/16446), which seems possibly related.

cc @nikomatsakis and @pcwalton whom i suspect will want to either weigh in, or simply squash the discussion before it baloons out of control as others have. 😉

---

<div class="post-metadata">

**Author:** ![l0kod](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/l0kod/32/198_2.png) [@l0kod](https://internals.rust-lang.org/u/l0kod)\
**Post date:** [September 3, 2014, 5:20pm UTC](https://internals.rust-lang.org/t/if-int-has-the-wrong-size/454/3 "2014-09-03T17:20:28Z")

</div>

> [@pnkfelix](#):
>
> That RFC suggested `intptr_t` / `uintptr_t`

The [RFC PR 161](https://github.com/rust-lang/rfcs/pull/161) suggests `index` or `intptr` as alternative names. Other ideas: `size`, `offset`.

---

<div class="post-metadata">

**Author:** ![glaebhoerl](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/glaebhoerl/32/1978_2.png) [@glaebhoerl](https://internals.rust-lang.org/u/glaebhoerl)\
**Post date:** [September 3, 2014, 6:13pm UTC](https://internals.rust-lang.org/t/if-int-has-the-wrong-size/454/4 "2014-09-03T18:13:29Z")

</div>

One problem with names like `index`, `size`, and `offset`, besides the plain lack of familiarity, is that it might not be immediately obvious that this is an integer type at all. Perhaps names like `isize` and `usize` could help with this (this is harder with `index` because it already starts with an ‘i’).

---

<div class="post-metadata">

**Author:** ![l0kod](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/l0kod/32/198_2.png) [@l0kod](https://internals.rust-lang.org/u/l0kod)\
**Post date:** [September 3, 2014, 6:38pm UTC](https://internals.rust-lang.org/t/if-int-has-the-wrong-size/454/5 "2014-09-03T18:38:07Z")

</div>

Maybe `index` for `int` and `size` for `uint`?

> [@glaebhoerl](#):
>
> besides the plain lack of familiarity, is that it might not be immediately obvious that this is an integer type at all.

That may be a good point to have an unfamiliar type name.

Anyway, the goal is also to encourage peoples to ask themselves "do I really need an architecture-related type here?".

---

<div class="post-metadata">

**Author:** ![glaebhoerl](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/glaebhoerl/32/1978_2.png) [@glaebhoerl](https://internals.rust-lang.org/u/glaebhoerl)\
**Post date:** [September 3, 2014, 8:26pm UTC](https://internals.rust-lang.org/t/if-int-has-the-wrong-size/454/6 "2014-09-03T20:26:39Z")

</div>

My point was that having ‘i’ and ‘u’ prefixes (whatever name they’re prefixed to) would make the connection to `i8`…`i64` and `u8`…`u64` more obvious, and help comprehensibility.

(For example, if I saw a type name like `size` without any prefix, my first association might be to [`QSize`](http://qt-project.org/doc/qt-4.8/qsize.html) rather than to [`size_t`](http://en.wikipedia.org/wiki/C_data_types#Size_and_pointer_difference_types).)

---

<div class="post-metadata">

**Author:** ![pnkfelix](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/pnkfelix/32/110_2.png) [@pnkfelix](https://internals.rust-lang.org/u/pnkfelix)\
**Post date:** [September 4, 2014, 5:33am UTC](https://internals.rust-lang.org/t/if-int-has-the-wrong-size/454/7 "2014-09-04T05:33:53Z")

</div>

I agree that keeping `i` and `u` as the first letters of whatever types we use could be good here.

I had a recent thought that maybe part of the problem is the instance on using the same suffix for both `i` and `u` in the pointer-sized case.

I.e., maybe if we took off that implicit constraint, then we could arrive somewhere interesting, like `uaddr` and `ioffset`. (Since, you know, the signed case arsies from pointer arithmetic and thus it makes sense to talk about as a _releative_ offset versus the unsigned being an _absolute_ address.

- Of course, going down that road might lead one to them attempt to encode rules in the types like `uaddr + ioffset -> uaddr` and make addition of `uaddr` itself illegal, while `uaddr - uaddr -> ioffset`. Kind of funny looking. Maybe this is more appropriate for a private newtyped library of my own rather than the core language.

---

<div class="post-metadata">

**Author:** ![l0kod](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/l0kod/32/198_2.png) [@l0kod](https://internals.rust-lang.org/u/l0kod)\
**Post date:** [September 4, 2014, 6:20am UTC](https://internals.rust-lang.org/t/if-int-has-the-wrong-size/454/8 "2014-09-04T06:20:06Z")

</div>

> [@pnkfelix](#):
>
> Of course, going down that road might lead one to them attempt to encode rules in the types like `uaddr` + `ioffset` -\> `uaddr` and make addition of `uaddr` itself illegal, while `uaddr` - `uaddr` -\> `ioffset`. Kind of funny looking. Maybe this is more appropriate for a private newtyped library of my own rather than the core language.

Well, this reflect the pointer arithmetic that Rust try to avoid, so it may be a good point. Anyway, a cast is still possible and more explicit about the danger the developer will be facing to.

I like the `ioffset`, but for `range` attributes we may prefer an unsigned type, which could also make sense with a `usize` because the range should be able to handle a collection size/length and a `len()` is often (in other languages) used as a `for` upper bound.

A `usize` will be more explicit than the `uaddr` (a size must always be positive) and is more abstract than an address. A `ulength` or `ulen` type make sense too.

---

<div class="post-metadata">

**Author:** ![petrochenkov](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/petrochenkov/32/2784_2.png) [@petrochenkov](https://internals.rust-lang.org/u/petrochenkov)\
**Post date:** [September 5, 2014, 6:50am UTC](https://internals.rust-lang.org/t/if-int-has-the-wrong-size/454/9 "2014-09-05T06:50:48Z")

</div>

What about floating point fallback?  
The lack of it creates relatively more inconvenience than the lack of integer fallback. (Although I’m still against both of them).

As for bikeshedding:  
int / uint -\> idx / uidx integer fallback -\> no (or i32) floating point fallback -\> no (or f64)

---

<div class="post-metadata">

**Author:** ![glaebhoerl](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/glaebhoerl/32/1978_2.png) [@glaebhoerl](https://internals.rust-lang.org/u/glaebhoerl)\
**Post date:** [September 5, 2014, 1:36pm UTC](https://internals.rust-lang.org/t/if-int-has-the-wrong-size/454/10 "2014-09-05T13:36:29Z")

</div>

It’s true that a signed value makes more semantic sense as some kind of relative value (offset), and an unsigned one as an absolute one (size). But I’m not sure if this outweighs the fact that from a principle-of-least-surprise perspective, I would really expect the signed and unsigned versions of the type to have the same name apart from the prefix (again, just like all of the other fixed-size integer types).

Anyways, coming out: my personal preference right now would in fact be for `isize` and `usize`. These are the first names that have come up as possibilities in the whole discussion so far (going back to the threads on GitHub) which cross the threshold of being non-awkward enough that I could actually conceive of them replacing `int` and `uint`.

---

<div class="post-metadata">

**Author:** ![iopq](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/iopq/32/78_2.png) [@iopq](https://internals.rust-lang.org/u/iopq)\
**Post date:** [September 5, 2014, 4:05pm UTC](https://internals.rust-lang.org/t/if-int-has-the-wrong-size/454/11 "2014-09-05T16:05:04Z")

</div>

I agree, there is no way to to see `offset` and expect the person to be able to derive `size` from it. It feels like a special case.

The correct term for it is `word` but assembler kind of spoiled it (why is it `QWORD` for 64 bits? It’s clearly the word size on my processor). I guess `isize` and `usize` is fine

---

<div class="post-metadata">

**Author:** ![tbu](https://avatars.discourse-cdn.com/v4/letter/t/839c29/32.png) [@tbu](https://internals.rust-lang.org/u/tbu)\
**Post date:** [September 5, 2014, 5:25pm UTC](https://internals.rust-lang.org/t/if-int-has-the-wrong-size/454/12 "2014-09-05T17:25:33Z")

</div>

The C semi-equivalent would be `size_t` and `ssize_t`, or Rustified maybe `size` and `ssize`.

---

<div class="post-metadata">

**Author:** ![rkjnsn](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/rkjnsn/32/5368_2.png) [@rkjnsn](https://internals.rust-lang.org/u/rkjnsn)\
**Post date:** [September 11, 2014, 11:22pm UTC](https://internals.rust-lang.org/t/if-int-has-the-wrong-size/454/13 "2014-09-11T23:22:01Z")

</div>

I like `isize` and `usize`, as they’re short enough, get the point across, are familiar to those coming from C, and match the prefixes used for other integer types.

---

<div class="post-metadata">

**Author:** ![CloudiDust](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/cloudidust/32/197_2.png) [@CloudiDust](https://internals.rust-lang.org/u/CloudiDust)\
**Post date:** [September 12, 2014, 3:33am UTC](https://internals.rust-lang.org/t/if-int-has-the-wrong-size/454/14 "2014-09-12T03:33:59Z")

</div>

+1 to `usize/isize`, also +1 to `i32/u32` as the default signed/unsigned integer type.

---

<div class="post-metadata">

**Author:** ![pnkfelix](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/pnkfelix/32/110_2.png) [@pnkfelix](https://internals.rust-lang.org/u/pnkfelix)\
**Post date:** [September 12, 2014, 10:20am UTC](https://internals.rust-lang.org/t/if-int-has-the-wrong-size/454/15 "2014-09-12T10:20:40Z")

</div>

> [@l0kod](#):
>
> A usize will be more explicit than the uaddr (a size must always be positive) and is more abstract than an address. A ulength or ulen type make sense too.

You know, i think this note gets at why I _prefer_ `uaddr` over `usize`: this type should not be considered abstract, as it is very much tied to the underlying machine architecture, no?

(Having said that, I'd probably take `usize`/`isize` over today's `uint`/`int`.)

* * *

A separate note: I am still concerned about my end note:

> [@pnkfelix](#):
>
> In any case, renaming the current int to _(whatever)_ is probably not enough on its own, because I suspect the type names int and uint (and likewise the suffixes i and u) are too sweet to give up. So then, what do we use them for?

But perhaps people are indeed suggesting we throw out `int`/`uint`, and repurpose the `i`/`u` suffixes for `isize`/`usize` ?

---

<div class="post-metadata">

**Author:** ![gioele](https://avatars.discourse-cdn.com/v4/letter/g/8491ac/32.png) [@gioele](https://internals.rust-lang.org/u/gioele)\
**Post date:** [September 12, 2014, 11:54am UTC](https://internals.rust-lang.org/t/if-int-has-the-wrong-size/454/16 "2014-09-12T11:54:22Z")

</div>

With the introduction if `isize`/`usize`, what will be the type of `i` in

```rust
for i in range(0u, 10) {
    println!("i = {}", i);
}

```

An iterator of type `usize` strikes me as very unnatural.

---

<div class="post-metadata">

**Author:** ![benh](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/benh/32/4955_2.png) [@benh](https://internals.rust-lang.org/u/benh)\
**Post date:** [September 12, 2014, 12:40pm UTC](https://internals.rust-lang.org/t/if-int-has-the-wrong-size/454/17 "2014-09-12T12:40:17Z")

</div>

If we go for isize, usize, We should change the suffixes away from i/u too, since them being that short only really makes sense if we want to push people towards habitually using them.

```
for i in range(0usize, 10) { println!("i = {}", i; }

```

“Wow that looks gross! I better use u32!”

```
for i in range(0u32, 10) { println!("i = {}", i; }

```

Mission accomplished!

---

<div class="post-metadata">

**Author:** ![glaebhoerl](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/glaebhoerl/32/1978_2.png) [@glaebhoerl](https://internals.rust-lang.org/u/glaebhoerl)\
**Post date:** [September 12, 2014, 1:34pm UTC](https://internals.rust-lang.org/t/if-int-has-the-wrong-size/454/18 "2014-09-12T13:34:14Z")

</div>

> [@pnkfelix](#):
>
> You know, i think this note gets at why I prefer uaddr over usize: this type should not be considered abstract, as it is very much tied to the underlying machine architecture, no?

The thing is that, outside of `unsafe` code, Rust programs do not and should not ever have to think about raw memory addresses. We have safe reference and box types whose semantics are defined abstractly and do not expose any notion of a machine-level memory address. Thus it seems strange for the naming of these types to reflect this low-level detail, because they are not primarily intended for use only with `unsafe` code. (This is the same thing which felt off to me about the earlier suggestions for `intptr` and `uintptr`.)

The aspect which safe Rust code (i.e. what should be the vast majority of Rust code) cares about is that these are the types which are appropriate for representing the sizes of and indexes into arrays (and presumably other kinds of collections as well).

> [@pnkfelix](#):
>
> A separate note: I am still concerned about my end note:
> 
> pnkfelix said: In any case, renaming the current int to (whatever) is probably not enough on its own, because I suspect the type names int and uint (and likewise the suffixes i and u) are too sweet to give up. So then, what do we use them for?
> 
> But perhaps people are indeed suggesting we throw out int/uint, and repurpose the i/u suffixes for isize/usize ?

This is indeed an interesting follow-on question, and also ties into the choice of the default type for integer literals.

The defining characteristic of the `int` and `uint` types, resp. `i` and `u` suffixes are that, because they're so "sweet" and culturally ingrained, they're what people will habitually use whenever they don't feel like thinking about it. Basically, the implied meaning of a type called "int" is that this is the type which it's appropriate to use "most of the time".

The question is whether such a type exists. _Is_ there an integer type which it is appropriate to use "most of the time"? My feeling is that we should have a type called `int`, defined as this type, if and only if such a type exists. In other words, if by giving them a type called `int`, we won't be giving people a false sense of security and leading them into mistakes. If, most of the time, you can't avoid having to think about the correct choice of type without implicating the correctness of the program, then we would be doing our users no favors by pretending otherwise, and it would be preferable to force a decision.

The only remotely plausible candidates for being `int` are `i32`, `i64`, and `isize`. One thing we could do is try to collect data, not necessarily about which type _is used_, but which types would _be correct_ for the types of integers in existing Rust code. (There is the possibility that more than one of these would be correct, i.e. that it doesn't matter, and also that none of them would, e.g. that you actually want `i8`.) If we find a clear majority for any of the three then most likely that type should be `int`. Otherwise, most likely none of them should. (Conversely, if we find lots of cases where `int` is used and it's not correct, then that might be an argument against having an `int`.) But doing this would probably be a whole lot of effort.

(Most of the above discussion should also apply equally to `uint`, the `u` suffix, `u32`, `u64`, and `usize`, in the case where the programmer knows that she wants an unsigned type, but not what size.)

---

<div class="post-metadata">

**Author:** ![glaebhoerl](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/glaebhoerl/32/1978_2.png) [@glaebhoerl](https://internals.rust-lang.org/u/glaebhoerl)\
**Post date:** [September 12, 2014, 1:41pm UTC](https://internals.rust-lang.org/t/if-int-has-the-wrong-size/454/19 "2014-09-12T13:41:14Z")

</div>

> [@benh](#):
>
> If we go for isize, usize, We should change the suffixes away from i/u too, since them being that short only really makes sense if we want to push people towards habitually using them.
> 
> ```
> for i in range(0usize, 10) { println!("i = {}", i; }
> 
> ```

(FWIW I think we could have `0is` and `0us` be the suffixes for `isize` and `usize`, if we decide that `i` and `u` shouldn't be.)

---

<div class="post-metadata">

**Author:** ![CloudiDust](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/cloudidust/32/197_2.png) [@CloudiDust](https://internals.rust-lang.org/u/CloudiDust)\
**Post date:** [September 13, 2014, 1:16am UTC](https://internals.rust-lang.org/t/if-int-has-the-wrong-size/454/20 "2014-09-13T01:16:50Z")

</div>

I think the same but am a little concerned about `is` and `us` being two actual words with other meanings, especially `is`. In practice this should not be a problem though.

Also we can repurpose `i`/`u` to mean `i32`/`u32`.

[Next page](https://internals.rust-lang.org/t/if-int-has-the-wrong-size/454.md?page=2)
