valeriyvan
(Valeriy Van)
1
Hi.
Found out that following equality testing compiles.
let int32: Int32 = 123456
if int32 == Int.max { }
Should this compile at all? Does this make sense?
Regards,
Valeriy Van
cukr
2
6 Likes
lukasa
(Cory Benfield)
3
This is a well-defined question to ask. For any two integer types with the same signedness you can transform the smaller type to the larger type and then issue the comparison directly. In this case, you can transform Int32 to Int, as all Int32s can be represented uniquely as a value in Int. The comparison is the equivalent to if Int(int32) == Int.max.
If you have two integer types of different signedness you can apply the same transformation, but in some edge cases you may need to confirm that the signed integer is not negative before applying the transformation into the unsigned type (as not all values of Int64 can be uniquely represented in UInt64).
2 Likes
tera
4
Shouldn't the same logic apply to +, etc?
1 Like
Nah. == is commutative. I don't want to have to think about the result type being the one on the left or right foot side.
2 Likes
jrose
(Jordan Rose)
6
To expand on Jessy’s response, the way to think about someInt == someInt32 isn’t “the Int32 gets converted to Int because Int is bigger”; it’s “if we converted both to an infinitely-sized (signed) integer type, would they be equal?”
4 Likes
tera
7
Would it be a problem if the following was allowed in swift?
func foo(_ v: Int) {}
var x: Int = 123
var y: Int8 = 1
x = x + y
x = y + x
x += y
foo(x + y)
foo(y + x)
let w = x + y // Error, or "choose "the greatest" type (in this case Int)"
let w: Int = y + x // ok
Ben_Cohen
(Ben Cohen)
8
Yes, this kind of one-way widening implicit conversion has long been considered a valid future direction to consider, but to do it well requires some very careful design and implementation (for example, in how the allowed conversions could be expressed by type authors, with the one-way nature of the conversions validated by the compiler).
1 Like
The last one is okay. (intTypeX + intTypeY) as IntTypeZ implies to me that the operation is happening within an IntTypeZ container, i.e. both operands get converted to it beforehand, or something equivalent to that. I wouldn't want it if the result type were not explicit.
Nobody1707
(Nobody1707)
10
To me that implies that the conversion happens after the addition, which doesn't seem as useful for a widening conversion. But maybe that's just my C-addled brain.