Yesterday, I’ve come to a reddit comment that complains the usage of unsigned integer types in
std. I found this interesting, especially:
just find Going Native 2013 conference video called “ask us anything” where all the C++ gurus discuss size_t and integer types and that using size_t in STL was a really big mistake.
in my opinion as I said, it’s a non-technical question at the end. “I’m writing an API, what type should I use?”, and the answer here should be as simple as possible.
I know this rant. It probably came from the well-known fact that mixing signed and unsigned arithmetic is dangerous in C/C++. At least, unconscious programmers may make mistakes due to this. As many of you may have known already, Google has a similar coding style guideline.
As he mentioned some other languages that use a signed integer as a container length type, I decided to find out what languages use a signed integer as a container length type. And I got a surprising result: Among the languages I’ve investigated, only D used unsigned as a length type. All the other languages, including Swift, Go, Haskell, Java, C#, and Ocaml all use a signed integer. Some languages inherently don’t have the unsigned type (like Java), but some languages, such as Swift, specifically states not to use unsigned.
I think there’s a reason behind this. As Rust has overflow/underflow checks, the risk of the misuses of the unsigned types is relatively low. But we can still make mistakes, and the checks are currently disabled in the release builds. That may be the reason why Swift, which is an overflow-checking language, still discourages the uses of the unsigned types.
And there’s one more advantage. Unlike
isize can be trivially casted from
i32, although this is not the case in 16-bit systems. Currently we don’t have any integer type coercions, but if we decide to add some as a limited form in the future, sticking to
isize may help.
One counter-argument to this might be the fact that the unsigned types prevent some illegal values, thus help catching bugs in advance. This is a good point, although some may raise a counter-counter-argument that even in the case, the types still allow some positive (large) illegal values.
I admit this is just a matter of a style. This is more likely a cultural thing. But it can impact the way we design the container APIs. Like the reddit user said, many crates will be modeled after
std in the future.
Unfortunately, the most effective counter-argument to this would be that we already released a beta. We should be really careful before making another breaking change. But I feel some kinds of anxiety that if this is really a problem, keeping this in 1.0 will be problematic in the future. But I really hope I was wrong. Any thoughts on this? I tried to find some relevant information in the forum and the RFC repository, but couldn’t find one.