# Forbid -(unsigned integer)

**URL:** <https://internals.rust-lang.org/t/forbid-unsigned-integer/752>\
**Category:** ideas (deprecated)\
**Created:** [November 5, 2014, 5:10pm UTC](https://internals.rust-lang.org/t/forbid-unsigned-integer/752 "2014-11-05T17:10:38Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![nodakai](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/nodakai/32/6161_2.png) [@nodakai](https://internals.rust-lang.org/u/nodakai)\
**Post date:** [November 5, 2014, 5:10pm UTC](https://internals.rust-lang.org/t/forbid-unsigned-integer/752/1 "2014-11-05T17:10:38Z")

</div>

We already have a lint item to find an application of the unary minus on an unsigned machine integer. Shouldn’t we simply forbid it? Rust programmers can always use `0 - x` instead when they know what they are doing (rustc eventually translates `-x` into `0 - x` because [LLVM doesn’t have the unary minus](http://llvm.org/docs/LangRef.html).)

---

<div class="post-metadata">

**Author:** ![arcto](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/arcto/32/45_2.png) [@arcto](https://internals.rust-lang.org/u/arcto)\
**Post date:** [November 5, 2014, 6:21pm UTC](https://internals.rust-lang.org/t/forbid-unsigned-integer/752/2 "2014-11-05T18:21:18Z")

</div>

I don’t think it should be forbidden. Perhaps it would be a good candidate for a lint that could warn about constant expressions resulting in trying to eval a negative unsigned value (including `a-b`, where it’s known that `b>a`) unless in an `unsafe` block.

---

<div class="post-metadata">

**Author:** ![nrc](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/nrc/32/126_2.png) [@nrc](https://internals.rust-lang.org/u/nrc)\
**Post date:** [November 5, 2014, 8:18pm UTC](https://internals.rust-lang.org/t/forbid-unsigned-integer/752/3 "2014-11-05T20:18:00Z")

</div>

It’s really useful for bit twiddling - `-1u` is the easiest way to fill a uint with 1s, for example. Given that we’re a systems language it is important to support this kind of thing.

---

<div class="post-metadata">

**Author:** ![nodakai](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/nodakai/32/6161_2.png) [@nodakai](https://internals.rust-lang.org/u/nodakai)\
**Post date:** [November 5, 2014, 11:16pm UTC](https://internals.rust-lang.org/t/forbid-unsigned-integer/752/4 "2014-11-05T23:16:18Z")

</div>

> [@nrc](#):
>
> -1u is the easiest way to fill a uint with 1s, for example.

No, it is just a more obscure way of writing `!0u`. [[playpen]](http://is.gd/HStQu7)

A good systems language should discourage people from writing such obscure codes. We should use arithmetic operators for doing arithmetic, bit operators for bit twiddling.

---

<div class="post-metadata">

**Author:** ![comex](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/comex/32/2587_2.png) [@comex](https://internals.rust-lang.org/u/comex)\
**Post date:** [November 6, 2014, 12:12am UTC](https://internals.rust-lang.org/t/forbid-unsigned-integer/752/5 "2014-11-06T00:12:28Z")

</div>

Obscure is relative - I think -1 is more common than ~0 for this purpose in C code, although the latter is pretty common as well.

---

<div class="post-metadata">

**Author:** ![nodakai](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/nodakai/32/6161_2.png) [@nodakai](https://internals.rust-lang.org/u/nodakai)\
**Post date:** [November 6, 2014, 6:51am UTC](https://internals.rust-lang.org/t/forbid-unsigned-integer/752/6 "2014-11-06T06:51:17Z")

</div>

> [@comex](#):
>
> -1 is more common

Talking of C, it doesn't really yield an `int` with all bits set with [one's complement number system](http://stackoverflow.com/a/186333/1190965) 😜

---

<div class="post-metadata">

**Author:** ![comex](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/comex/32/2587_2.png) [@comex](https://internals.rust-lang.org/u/comex)\
**Post date:** [November 6, 2014, 6:12pm UTC](https://internals.rust-lang.org/t/forbid-unsigned-integer/752/7 "2014-11-06T18:12:52Z")

</div>

Actually, signed-\>unsigned conversion in C is guaranteed to be treated as if two's complement were used:

> Otherwise, if the new type is unsigned, the value is converted by repeatedly adding or subtracting one more than the maximum value that can be represented in the new type until the value is in the range of the new type.

---

<div class="post-metadata">

**Author:** ![mcpherrinm](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/mcpherrinm/32/422_2.png) [@mcpherrinm](https://internals.rust-lang.org/u/mcpherrinm)\
**Post date:** [November 7, 2014, 7:44pm UTC](https://internals.rust-lang.org/t/forbid-unsigned-integer/752/8 "2014-11-07T19:44:51Z")

</div>

You can’t use !0u64 in, for example, a match statement, like in this playpen link: [http://is.gd/9Oic3G](http://is.gd/9Oic3G)

---

<div class="post-metadata">

**Author:** ![kennytm](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/kennytm/32/161_2.png) [@kennytm](https://internals.rust-lang.org/u/kennytm)\
**Post date:** [November 8, 2014, 7:52am UTC](https://internals.rust-lang.org/t/forbid-unsigned-integer/752/9 "2014-11-08T07:52:38Z")

</div>

In this case you could use `std::u64::MAX` instead.

---

<div class="post-metadata">

**Author:** ![Gankra](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/gankra/32/6002_2.png) [@Gankra](https://internals.rust-lang.org/u/Gankra)\
**Post date:** [November 8, 2014, 1:41pm UTC](https://internals.rust-lang.org/t/forbid-unsigned-integer/752/10 "2014-11-08T13:41:54Z")

</div>

While I appreciate the bitfiddly explanation here, this has caused people enough trouble for people that I’m inclined to just say we should kill it. As has been noted `!foo`, `u64::MAX - foo` and `0 - foo` are all viable options for achieving the same results, depending on what you’re trying to accomplish. `-foo` is in my opinion the semantically worst one, because to many people it just looks like a logic error.

There are _several_ idioms in C/C++ programming that Rust explicitly doesn’t support, presumably because they’re troublesome in practice. I see no reason to support this one.

---

<div class="post-metadata">

**Author:** ![comex](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/comex/32/2587_2.png) [@comex](https://internals.rust-lang.org/u/comex)\
**Post date:** [November 8, 2014, 11:45pm UTC](https://internals.rust-lang.org/t/forbid-unsigned-integer/752/11 "2014-11-08T23:45:58Z")

</div>

I really have a hard time seeing how 0 - x is less of a logic error than -x or why it should be any different…

---

<div class="post-metadata">

**Author:** ![Gankra](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/gankra/32/6002_2.png) [@Gankra](https://internals.rust-lang.org/u/Gankra)\
**Post date:** [November 9, 2014, 2:57pm UTC](https://internals.rust-lang.org/t/forbid-unsigned-integer/752/12 "2014-11-09T14:57:06Z")

</div>

`0 - x` is using a binary subtraction operator. Something unsigned integers _must_ support. `-x` is unary negation, something that doesn’t make a ton of sense for an unsigned integer to support unless you’re using it as a collection of bits, or a ring. These are of course perfectly valid use cases, and are fully supported by Rust.

However unless the domain clearly identifies the numbers in question as being used in such a manner, `-x` is something that I would expect to be a programmer error on a `uint`. `0 - x` is something that is just trivially allowed by providing binary subtraction. I mean, we could lint against it too, but I don’t think that’s necessary.

I am highly doubtful that the core team is going to let unary negation of unsigned integers go away, though. It has been given the stamp of approval on several occasions before, and I don’t think they’re going to backtrack on it. It’s just going to be one of those errors tons of people make.

---

<div class="post-metadata">

**Author:** ![arthurprs](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/arthurprs/32/233_2.png) [@arthurprs](https://internals.rust-lang.org/u/arthurprs)\
**Post date:** [January 13, 2015, 2:39am UTC](https://internals.rust-lang.org/t/forbid-unsigned-integer/752/13 "2015-01-13T02:39:25Z")

</div>

Just got bit by this using -1 as the step in range\_step.

Is there a better way to reverse iterate an usize? This is how I'm doing right now

> for pp in range\_step((n - 1) as isize, 0, -1) { let p = pp as usize;

---

<div class="post-metadata">

**Author:** ![Gankra](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/gankra/32/6002_2.png) [@Gankra](https://internals.rust-lang.org/u/Gankra)\
**Post date:** [January 13, 2015, 4:45am UTC](https://internals.rust-lang.org/t/forbid-unsigned-integer/752/14 "2015-01-13T04:45:38Z")

</div>

`for pp in range(0, n).rev()`

---

<div class="post-metadata">

**Author:** ![nodakai](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/nodakai/32/6161_2.png) [@nodakai](https://internals.rust-lang.org/u/nodakai)\
**Post date:** [January 13, 2015, 10:00am UTC](https://internals.rust-lang.org/t/forbid-unsigned-integer/752/15 "2015-01-13T10:00:19Z")

</div>

Patterns like 100, 96, 92, 88, … will be a bit non-intuitive if we write them by the combination of `range()` (or the range syntax) and `Iterator::rev()`…

---

<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:** [January 17, 2015, 7:09am UTC](https://internals.rust-lang.org/t/forbid-unsigned-integer/752/16 "2015-01-17T07:09:07Z")

</div>

@nodakai, yeah this can be non-intuitive. (And while the returned iterators of `range` can be reversed, `range_step` iterators are not double-ended, which means the reversal of them cannot be iterated over.)

Maybe some enhancement can be made to range notations for this use case?

I believe the current important thing here is that by forbiding `-(unsigned integer)` we can avoid the _hard-to-spot_ bug that @arthurprs encountered. (It is very hard to _constantly_ stay aware of the value range of unsigned integers without the compiler’s help.) I propose that you file an RFC for this change.

---

<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:** [January 17, 2015, 9:21am UTC](https://internals.rust-lang.org/t/forbid-unsigned-integer/752/17 "2015-01-17T09:21:16Z")

</div>

I agree with disallowing this. As has been pointed out, there are several ways to express the same thing that are clearer, more explicit, and less likely to lead to errors from accidentally passing a negative constant as an unsigned quantity.

Also, if the RFC to consider wrapping a logic error by default is accepted, allowing unsigned negation would seem pretty weird.

---

<div class="post-metadata">

**Author:** ![nagisa](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/nagisa/32/2210_2.png) [@nagisa](https://internals.rust-lang.org/u/nagisa)\
**Post date:** [January 17, 2015, 4:57pm UTC](https://internals.rust-lang.org/t/forbid-unsigned-integer/752/18 "2015-01-17T16:57:13Z")

</div>

> [@Gankra](#):
>
> 0 - x is using a binary subtraction operator. Something unsigned integers must support.

This won’t work when/if the overflow checking is implemented, though, unless `x` is of type `Wrapping<T>`.

From my own experience doing bit fiddling (and I’ve been doing a lot of that lately), I prefer either `0xFFFF_FFFF_…` or `!0` and lack of `-1u` would’t bother me (0 uses across all code I wrote in Rust and other languages alike) a tiny bit.

---

<div class="post-metadata">

**Author:** ![nodakai](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/nodakai/32/6161_2.png) [@nodakai](https://internals.rust-lang.org/u/nodakai)\
**Post date:** [January 18, 2015, 2:01am UTC](https://internals.rust-lang.org/t/forbid-unsigned-integer/752/19 "2015-01-18T02:01:02Z")

</div>

Right, the removal of the wrapping semantics by default will make it impossible to provide an handy but exact way to replace `-unsigned_int` in general (I don’t think people will find it convenient to write `!unsigned_int + 1`…)

```
const X: u32 = !10 + 1;
const Y: u32 = -10;

fn main() {
    println!("{}", X);
    println!("{}", Y);
}

```

[[playpen]](http://is.gd/OZRkt0)

---

<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:** [January 18, 2015, 2:25am UTC](https://internals.rust-lang.org/t/forbid-unsigned-integer/752/20 "2015-01-18T02:25:49Z")

</div>

@nodakai, personally I don’t find `!unsigned_int + 1` to be annoying.

Also, If `0 - unsigned_int` is an error due to overflowing, then it will be strange if `-unsigned_int` is not an error. (Because the programmer is requesting a value outside the valid range of unsigned ints, even though his/her true intention is `!unsigned_int + 1`.)

On the other hand, `!unsigned_int` is _explicit_ bit flipping, where the programmer is _not_ wanting a negative value. So it should always be a valid operation.

EDIT: Sorry I didn’t make myself clear. My opinion is that we should implement “error on overflowing” even if that means both `0 - unsigned_int` and `-unsigned_int` will be invalid and we will have to write `!unsigned_int + 1`. (That is if other concerns doesn’t stop us from doing so.)

[Next page](https://internals.rust-lang.org/t/forbid-unsigned-integer/752.md?page=2)
