5 ms·
Yes, but: > ..there's no reason why you couldn’t safely promote a u8, u16, or u32 into a usize, and asking programmers to manually cast integers everywhere mak
by colejohnson66 4y ago
Yes, but:
> ..there's no reason why you couldn’t safely promote a u8, u16, or u32 into a usize, and asking programmers to manually cast integers everywhere makes the code more noisy and verbose.
They have a valid point. In C#, numerical casts that won't lose precision are implicit, and any that could are explicit. I think that’s a nice compromise. So, int to uint requires a cast, but int/uint to long doesn't:
int myInt = /* ... */;
long myLong = myInt;
uint myUInt = myInt; // error CS0266: Cannot implicitly convert type 'int' to 'uint'. An explicit conversion exists (are you missing a cast?)
ulong myULong = myInt; // error CS0266: Cannot implicitly convert type 'int' to 'ulong'. An explicit conversion exists (are you missing a cast?)
uint myUInt = /* ... */;
int myInt = myUInt; // error CS0266: Cannot implicitly convert type 'uint' to 'int'. An explicit conversion exists (are you missing a cast?)
long myLong = myUInt;
ulont myULong = myUInt;
- stonemetal12 4y agou8 max value + 1 means something as a u8. u8 max value + 1 means something different as a u16. Implicitly changing behavior is never cool.
- colejohnson66 4y agoThat wouldn’t be an issue. The whole claim is that this: let a: u8 = /* */; let b: u16 = a; push_u16(a); can easily be inferred into: (no pun intended) let a: u8 = /* */; let b: u16 = a.into(); push_u16(a.into()); But the Rust language has decided that implicit upconversion that is already apparent is a bad idea because “bugs”. And I’d agree with them, but it’s stupid in this case. The issue at hand isn’t asking for ‘a’ to be upconverted to a u16 in the middle of an expression like this: let b: u16 = a + 1; …because you’d be left with the question of when to upconvert (“implicitly changing behavior” as you call it). No, it would only be when it shouldn’t need to be said such as a lone assignment or function call. And if the Rust language’s argument is that it’d be unclear when it’s allowed? Because I’ve seen many RFCs where someone does what you just did: “what about this weird corner case where ‘u8 max + 1’? Should that be a u8 or u16? Maybe we should toss the whole proposal!” To that I’d say: start off where it’s clear (like my examples above). It’s not a backwards incompatible change. /rant
- shepmaster 4y agoAnd chiming in: > there's no reason why you couldn’t safely promote a u8, u16, or u32 into a usize The people running Rust on a 16-bit architecture (e.g. AVR) would disagree. On those platforms, usize is 16-bit, so promoting u32 to usize would not be possible. I _do_ wish there was a nicer way to declare up-front "I *never* want this crate to compile on something smaller than 32-bit (or 64-bit), so assume that". IIRC, similar ideas like this have floated around under the name of a "platform compatibility lint".
- wahern 4y agoBut whether implicitly or explicitly converted, the compiler would reject the code all the same, no? (Unless an explicit conversion would actually succeed, which is even worse. I'm not a Rust programmer so don't know. But this is why explicit casts are frowned upon in C.)
- JoshTriplett 4y agoThe proposal is that by default the compiler would refuse to do an infallible conversion from `u32` to `usize`, but if you declare up front "this code assumes at least a 32-bit target", then you gain the ability to do infallible conversions from u32 to usize. And if you declare up front "this code assumes at least a 64-bit target", you gain the ability to do infallible conversions from u64 to usize. Also, you can already convert u8 and u16 to usize infallibly, today. Only u32 and u64 currently require fallible conversions via try_from.