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

Restore int fallback #16968

Closed
brson opened this issue Sep 3, 2014 · 26 comments · Fixed by #20189
Closed

Restore int fallback #16968

brson opened this issue Sep 3, 2014 · 26 comments · Fixed by #20189
Assignees
Labels
B-RFC-approved Blocker: Approved by a merged RFC but not yet implemented. C-enhancement Category: An issue proposing an enhancement or a PR with one. P-medium Medium priority
Milestone

Comments

@brson
Copy link
Contributor

brson commented Sep 3, 2014

rust-lang/rfcs#212

@vks
Copy link
Contributor

vks commented Sep 4, 2014

Is there a reason why int is preferred over i32 as a fallback? The latter seems like a safer choice (in terms of portability).

@brson brson added P-high and removed I-nominated labels Sep 4, 2014
@brson brson added this to the 1.0 milestone Sep 4, 2014
@brendanzab
Copy link
Member

+1 on @vks' comment.

@l0kod
Copy link
Contributor

l0kod commented Sep 5, 2014

I'm in favor of i32 and f32.

@vks
Copy link
Contributor

vks commented Sep 5, 2014

I think f64 is a more conservative choice because of the precision. Many other languages (i.e. Python) use it too.

(Personally, I've never wanted to use f32. I guess it is important when coding games, but the floating point errors are already bad enough with f64.)

@thestinger
Copy link
Contributor

C / C++ implementations use i32 and f64 for the unadorned literals (int and double) in practice, although the standards specify the minimum int as i16 and floating point types are allowed to have more precision and/or a higher radix.

@l0kod
Copy link
Contributor

l0kod commented Sep 5, 2014

Seems right to use f64 if it's OK for all architectures.

@alexchandel
Copy link

@vks int fallback is for ease of writing small programs, not portability; it shouldn't be used in production code. Remember, int's proper name is intptr, as C99's intptr_t, although it can store pointer differences, sizes, and array indices too, so does ptrdiff_t and size_t too.

I think int and f64 are reasonable fallback choices, although I'd rather see int renamed to intptr and have int and float just aliased to the largest native integer and floating points available (with a fallback for soft-fp systems).

@vks
Copy link
Contributor

vks commented Sep 17, 2014

@alexchandel Unfortunately this is not what the documentation teaches or uses. It does not even mention how int vs. i32, i64 should be used. Almost every example just uses int, which is almost never what you want. (The in my opinion only legitimate use of int I can think of right now is offset and similar pointer arithmetic, which does not occur in safe code.)

I think even small programs should not use int as it is currently defined. The current practice only works as long as the code does not need integers larger than what i32 can represent. So why not just use i32?

@l0kod
Copy link
Contributor

l0kod commented Sep 17, 2014

I'd rather see int renamed to intptr

About the int and uint name and use, there is #16446, #15526, rust-lang/rfcs#161 and http://discuss.rust-lang.org/t/if-int-has-the-wrong-size/454

@alexchandel
Copy link

@vks int is large enough to hold any memory address, so it's suitable for slicing, indexing, lengths, sizes, unsafe pointer arithmetic, etc. Actually, I just realized the main signature fn main(argc: int, argv: *const *const u8) -> int uses int correctly. It looks like the manual defines them correctly, but the guide doesn't cover the issue.

I don't like the idea of granting a special place in the language to a particular fixed-size type. Also I run into i32 overflow pretty often, so I prefer i64. The fallback int is for prototyping only, and should be as large as possible without significantly compromising speed (like an emulated 32-bit on a 16-bit microcontroller, or an emulated 128-bit on a cpu with only 64-bit registers and operations), so it should be target dependent.

@l0kod I think intptr and uintptr are the correct names, since intptr_t must be at least as large as size_t and ptrdiff_t. Also intptr_t and uintptr_t are the standard in C and C++. Using a newly coined name like "index", "offset", or "size" would add confusion. And isize/usize/offset are all incorrect in environments (like segmented memory) where the address space is larger than the maximum possible size. iaddr/uaddr are correct alternatives, but why invent a new name?

@thestinger
Copy link
Contributor

It does significantly compromise speed. It's up to 2x as slow as 32-bit integers on x86_64, on average in the range of 20-30% slower.

@thestinger
Copy link
Contributor

Rust doesn't support an environment where the address space and largest possible size are not equal. It would require a lot of work and widespread movement away from a unified int type to provide that kind of portability.

@alexchandel
Copy link

@thestinger I disagree, 20-30% slower integer operations is fine for prototyping. If you examine disassembled Rust on x86-64 OS X, you find that most of the operations are qword-sized already. Not to mention the fact that int is already 64-bits on x86-64 OS X and x86-64 Linux. And Rust's not supporting protected mode doesn't change the fact that the names are incorrect, or that intptr_t has broader meaning than ptrdiff_t or size_t.

@thestinger
Copy link
Contributor

The int type is 64-bit because it's guaranteed to be pointer size and cover all in-memory indexing / size needs. It's not currently a default in any sense.

@vks
Copy link
Contributor

vks commented Sep 18, 2014

@alexchandel

int is large enough to hold any memory address, so it's suitable for slicing, indexing, lengths, sizes, unsafe pointer arithmetic, etc.

In almost all of those example you rather want to (or even have to) use uint.

It looks like the manual defines them correctly, but the guide doesn't cover the issue.

The manual does not say how they are intended to be used.

I don't like the idea of granting a special place in the language to a particular fixed-size type. Also I run into i32 overflow pretty often, so I prefer i64. The fallback int is for prototyping only, and should be as large as possible without significantly compromising speed

If you prefer i64, you can use it. I don't think it is necessary for most non-production code and it sacrifices performance for no reason.

The fallback int is for prototyping only, and should be as large as possible without significantly compromising speed

int is not defined as a "reasonably fast but large" integer. It is pointer sized. Using it as a "fast" integer is abusing it IMHO. What you want does currently not exist in Rust.

Anyway, I don't really care which one will be the default, as long as it is not int.

@thestinger

It's not currently a default in any sense.

It is virtually a default, given the way int is currently used. It is implicitly advertised as a default in most documentation and examples.
I think most people learning Rust will be using int instead of the fixed size types, because of the way it is taught.

@l0kod
Copy link
Contributor

l0kod commented Sep 19, 2014

It is virtually a default, given the way int is currently used. It is implicitly advertised as a default in most documentation and examples.
I think most people learning Rust will be using int instead of the fixed size types, because of the way it is taught.

That's right. Moreover, one-letter suffixes like u and i are also to blame because they are so sweet to use. They looks like default integer types.

@thestinger
Copy link
Contributor

An existing problem isn't a sane rationale to create more problems.

@vks
Copy link
Contributor

vks commented Sep 19, 2014

@thestinger What are you referring to with "more problems"?

@thestinger
Copy link
Contributor

Restoring it as the fallback type when inference fails.

@brson brson self-assigned this Oct 1, 2014
@brson
Copy link
Contributor Author

brson commented Oct 1, 2014

I've assigned this to myself but I'm still working on automation and installation for now so would not mind if somebody else took it.

@brson brson removed their assignment Nov 3, 2014
@tbu-
Copy link
Contributor

tbu- commented Nov 5, 2014

Is there still agreement on that this is a good idea? It was an RFC that was merged pretty quick (within 7 days) – and afterwards discussions seemed to resolve in that int is a bad default, see e.g. Thoughts on numeric types.

@tbu-
Copy link
Contributor

tbu- commented Nov 5, 2014

Adding to that, if this ships with the 1.0 release, one can basically never go back, so it'd be best if the counter-points were addressed (which weren't addressed in the RFC), namely that int simply doesn't look like a good default

(It only talks about "missing bugs". However the same could be said about C code that, unless it's specifically targeted by attackers, usually does not expose bugs.)

@vks
Copy link
Contributor

vks commented Nov 5, 2014

I think the "no bugs yet" argument is not a good one, because at the moment most Rust developers are using x86-64. Portability bugs will arise when Rust gets widespread use on differing platforms.

Arguably #16755 is a portability bug in the standard library as of today.

@simias
Copy link

simias commented Nov 5, 2014

After reading through both comment threads I think I agree that while at first glance it sounds like a reasonable modification it seems to have the potential of becoming a bad default in certain cases. And it's not like the lack of fallback is that painful to work with, the compiler messages are generally very explicit and the suffixes are not generally very intrusive.

I mean, if you consider the examples in the RFC:

let mut m = HashMap::new();
m.insert(1, 2);
m.insert(3, 4);
assert_eq(m.find(&3).map(|&i| i).unwrap(), 4);

In today's rust would be:

let mut m = HashMap::new();
m.insert(1i, 2i);
m.insert(3, 4);
assert_eq(m.find(&3).map(|&i| i).unwrap(), 4);

And

for _ in range(0, 10) {
}

Becomes

for _ in range(0u, 10) {
}

The RFC states that it might deter newcomers but I think it's a moot point because if they come from C/C++ they still save massively on having to specify all the types and if they come from dynamically typed languages it might give them the false impression that those counter values have no type or are dynamically typed or that their type does not matter, which isn't strictly true in all the cases.

@tbu-
Copy link
Contributor

tbu- commented Nov 5, 2014

Note that in both examples, there's no reason to make the integers variable-width (except for that int is sounding defaultish), so fallback would silently hide that.

@nrc
Copy link
Member

nrc commented Dec 25, 2014

Note that since RFC PR #452 has been accepted, the fallback is to i32, not int.

bors added a commit that referenced this issue Dec 26, 2014
Doesn't yet converge on a fixed point, but generally works. A better algorithm
will come with the implementation of default type parameter fallback.

If inference fails to determine an exact integral or floating point type, it
will set the type to i32 or f64, respectively.

Closes #16968
bors added a commit that referenced this issue Dec 31, 2014
Doesn't yet converge on a fixed point, but generally works. A better algorithm
will come with the implementation of default type parameter fallback.

If inference fails to determine an exact integral or floating point type, it
will set the type to i32 or f64, respectively.

Closes #16968
bors added a commit that referenced this issue Jan 2, 2015
Doesn't yet converge on a fixed point, but generally works. A better algorithm
will come with the implementation of default type parameter fallback.

If inference fails to determine an exact integral or floating point type, it
will set the type to i32 or f64, respectively.

Closes #16968
lnicola pushed a commit to lnicola/rust that referenced this issue Apr 7, 2024
fix: silence mismatches involving unresolved projections

fix rust-lang#16801
lnicola pushed a commit to lnicola/rust that referenced this issue Apr 20, 2024
fix: silence mismatches involving unresolved projections

fix rust-lang#16801
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
B-RFC-approved Blocker: Approved by a merged RFC but not yet implemented. C-enhancement Category: An issue proposing an enhancement or a PR with one. P-medium Medium priority
Projects
None yet
Development

Successfully merging a pull request may close this issue.

10 participants