Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Guide: what to do about int #15526

Closed
steveklabnik opened this issue Jul 8, 2014 · 20 comments
Closed

Guide: what to do about int #15526

steveklabnik opened this issue Jul 8, 2014 · 20 comments
Labels
P-medium Medium priority

Comments

@steveklabnik
Copy link
Member

I've been using int because its familiar, but it may not be the right thing to suggest. Can we get a decision here?

@vks
Copy link
Contributor

vks commented Aug 8, 2014

I don't understand the issue. What decision needs to be made? int vs. uint? int vs. int32 vs. int64?

@steveklabnik
Copy link
Member Author

Int vs some sort of size. Generally, int is not actually what you want.

@vks
Copy link
Contributor

vks commented Aug 8, 2014

Do you know what the intended use of int is? It has the same size as uint, which is always large enough to represent a pointer. However, I don't think anyone uses int to represent pointers. So unlike uint, it does not have a clear use case.

Machines with 64-bit pointers often have 64-bit arithmetic, in which using i64 is not as expensive as on machines with 32-bit arithmetic only.
However, I think they do not always have 64-bit arithmetic, so this is not reliable.

If int was guaranteed to have 64 bits if a corresponding arithmetic is available, it could be useful.
In its current state, I can't think of a case where you would want to use int.
It seems to me that it is currently used when people don't care whether it is an i32 or i64. (At least that is how I use it.) Unfortunately that leads to unnecessarily platform-dependent code.

I think the most sensible default to use would be i32, because this should give decent performance on most modern platforms.

@vks
Copy link
Contributor

vks commented Aug 9, 2014

On uses of int:

Apparently the analogous type in C is used to store pointer offsets, which can be negative. See [1].
In Rust this is used by the unsafe offset method for raw pointers. [2]

So is it safe to say that int should only be used for such (unsafe) code?

[1] https://stackoverflow.com/questions/1464174/size-t-vs-intptr-t
[2] http://doc.rust-lang.org/std/ptr/trait.RawPtr.html#tymethod.offset

@l0kod
Copy link
Contributor

l0kod commented Aug 12, 2014

From #16446:

As discussed in rust-lang/rfcs#115 and #9940, the int and uint should only be used for memory-related values (e.g. length).

The documentations mostly use i suffix examples. It should encourage the use of fixed-size integer (e.g. u32) for common uses.

Except for range or size-related values, the guide should use fixed-size integer examples (e.g. Variable bindings section), probably u32 (for interoperability).

The guide should highlight the relation of int and uint with the architecture/memory (maybe with the x32 example, cf. #14758), and why it could be dangerous to use them for other means.

@1fish2
Copy link

1fish2 commented Aug 14, 2014

rust-lang/rust-guidelines#24 proposes integer style guidelines.

https://github.com/1fish2/Rust-rfcs/blob/int-index-for-portability/active/0000-intindex.md gives background on int and uint, common misconceptions, and interpretations of "default integer types."

In short, Rust defines integer types int and uint to be large enough to hold a pointer in the target environment. They aren't the fastest, "native," register, or C sized integers despite the names. They make sense for indexing and sizing in-memory containers, but using them for computations that are not limited by memory leads to code that's not portable to smaller-address targets than it was developed and tested on.

@pnkfelix
Copy link
Member

pnkfelix commented Sep 1, 2014

What we decide here is going to have an impact on the interface to some of the libraries, such as std::container::Bitv (as mentioned in #16736).

Nominating; suggest 1.0 P-backcompat-libs.

@brson
Copy link
Contributor

brson commented Sep 4, 2014

We should decide this, but not 1.0.

@aturon
Copy link
Member

aturon commented Sep 4, 2014

@steveklabnik Just to clarify, is the question here about what to do when there isn't an inferred type for integer literals (which will be resolved by reinstating the fallback), or API design, or some other place where you're recommending a type?

@pnkfelix I think that these API decisions can be made as part of the stabilization/guidelines process.

@steveklabnik
Copy link
Member Author

The question is, right now I annotate every single literal with i, until
the whole question about what to do shakes out.

It currently looks like fallback is gonna eventually get accepted, so this
won't matter, as the fallback can handle it.

@vks
Copy link
Contributor

vks commented Sep 18, 2014

@brson

We should decide this, but not 1.0.

I'm not sure this is a good idea. It breaks backwards compatibility if some interface changes from using int to using i32. Also, a lot of people will learn Rust when 1.0 is released, so it would be good if they are not taught soon-to-be-deprecated habits like using int instead of fixed size integers.

@alexchandel
Copy link

@steveklabnik
This issue is independent of whether int becomes the "fallback" type, no? It's what type should the guide use.

Just recently, I pointed a friend to the guide. He's a systems/embedded programmer (one of the reasons I suggested Rust), and the first thing he asked was what the size of int was. When I explained, he immediately understood what a "pointer-sized integer" meant, but he felt the guide's examples were wrong since they exclusively used this type, and seemed to suggest it was for general data.

Having a pointer sized integer isn't confusing. Even calling it int isn't a problem. What is confusing is not documenting it as such. Having fixed-width types like i8, u8, i16, u16, i32, u32, i64, and u64 is a key feature of Rust, and some of these should be displayed in the guide. When the guide talks about subscripting an array, just mention that int is pointer-sized, and used for indexes, lengths, sizes, and offsets, analogous to size_t and intptr_t in C.

@vks

Also, a lot of people will learn Rust when 1.0 is released, so it would be good if they are not taught soon-to-be-deprecated habits like using int instead of fixed size integers.
Agreed, the guide should be using a fixed-width integer.

So, can we have a PR changing most of the ints in the Guide to i32s or i64s?

@steveklabnik
Copy link
Member Author

@alexchandel I see the fallback type and the type we reccomend as being for general use as being one and the same. Why fall back to the non-default type? that makes no sense.

I am on team 'fallback to i32.'

So, can we have a PR changing most of the ints in the Guide to i32s or i64s?

It's not worth doing until we make a conventions decision here.

@1fish2
Copy link

1fish2 commented Nov 5, 2014

Having a pointer sized integer isn't confusing. Even calling it int isn't a problem. What is confusing is not documenting it as such.

@alexchandel Unfortunately, many programmers don't fully read/grok/remember the docs. They'll make assumptions based on other languages. Thus calling it int is a problem.

@steveklabnik I agree about fallback to i32.

@alexchandel
Copy link

Unfortunately, many programmers don't fully read/grok/remember the docs. They'll make assumptions based on other languages. Thus calling it int is a problem.

@1fish2 I disagree, programmers have IQs above 42. And if someone is writing production code in Rust and they never learned what the base types are, then there's no helping them. But the name is changing, so it's moot.

Indeed, the guide has been changed to use i32 in its examples. Close?

@vks
Copy link
Contributor

vks commented Jan 6, 2015

@alexchandel Just look at arbitrary Rust code on github. Most uses of int are wrong.

@steveklabnik
Copy link
Member Author

Yes, this can be closed.

@1fish2
Copy link

1fish2 commented Jan 6, 2015

@steveklabnik Excellent. Cheers!

BTW, the Guide might want to say what i32 means when first using it.

Is there a doc on Rust's type inference?

@alexchandel No disrespect intended for my fellow programmers. It's not about intelligence. It's about design complexity & usability, busy people, project time pressures, limited working memory, using many languages on a daily basis, and jumping to conclusions.

To take one example, I've had fellow Google engineers not know about key Java facts like precise exceptions (which enables portability but severely limits code motion optimizations), which primitives are atomic in read/write, or how to write bounded generics. How many programmers have read the language spec of the languages they use?

Back to Rust, there have been many uses of int and uint where a non-portable integer type is inappropriate such as integer shift and rotate counts, basic math operations, and binary I/O.

@alexchandel
Copy link

@vks simply untrue.

@1fish2 There's a difference between knowing "which primitives are atomic in read/write" and what the definition of int is.

@1fish2
Copy link

1fish2 commented Jan 16, 2015

@alexchandel Yes, that was an extreme example. The point is it was a usability problem, not users' fault. Those weren't IQ 42 programmers surprised to learn via the Rust mailing list that int was non-portable. Nor IQ 42 programmers who selected int for integer shift and rotate counts, reading and writing 32-bit binary proto buffer fields, etc.

bors added a commit to rust-lang-ci/rust that referenced this issue Sep 18, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
P-medium Medium priority
Projects
None yet
Development

No branches or pull requests

9 participants