2

Swift

Integers in Swift are ok. They cannot be infinite like Doubles, thought. They have a limit.
Surpassing that limit will cause a crash.


Exhibit A
Int(10000000000000000000)
error: integer literal '10000000000000000000' overflows when stored into 'Int'


Exhibit B
Int(pow(Double(1000000000), Double(10)))
Fatal error: Double value cannot be converted to Int because the result would be greater than Int.max


I naively thought to myself, "Hey, this is a fatal error. Can I catch the error with a do, catch block?"
Nope


Exhibit C

do {
    Int(pow(Double(1000000000), Double(10)))
} catch {
    print("safety net")
}
print("good?")

warning: 'catch' block is unreachable because no errors are thrown in 'do' block
Fatal error: Double value cannot be converted to Int because the result would be greater than Int.max


Oh, yeah. That's right! I forgot to add try
Nope


Exhibit D

do {
    try Int(pow(Double(1000000000), Double(10)))
} catch {
    print("safety net")
}
print("good?")

warning: no calls to throwing functions occur within 'try' expression
warning: 'catch' block is unreachable because no errors are thrown in 'do' block
Fatal error: Double value cannot be converted to Int because the result would be greater than Int.max


What is going on?

Can anyone explain this to me? I would really like to be able to catch an error like this.
Thank you so much, this would be a huge help!

Community
  • 1
  • 1
0-1
  • 702
  • 1
  • 10
  • 30
  • 1
    The Swift runtime considers integer overflows as being runtime errors, and are thus not catchable exceptions. See [this question](https://stackoverflow.com/questions/35973899/how-does-one-trap-arithmetic-overflow-errors-in-swift). – Abion47 May 08 '20 at 18:52

1 Answers1

2

You can use the init(exactly:) constructor, it will not throw an error but it will return nil if the value is to large

guard let value = Int(exactly: pow(Double(1000000000), Double(10))) else {
    //error handling
}
Joakim Danielson
  • 43,251
  • 5
  • 22
  • 52
  • Thank you so much!! Unfortunately, putting ```NaN``` values in ```init(exactly:)``` causes an overflow: ```func test() { guard let value = Int(exactly: 0.0 / -0.0) else { return } }``` here's the error: ```error: invalid conversion: 'NaN' overflows 'Int?'``` There's probably another init method so I can do some research on this. Good answer! – 0-1 May 08 '20 at 19:01