3

I'm aware of the following Swift syntax forms which, when they fail, cause a runtime error / illegal instruction:

var x: Foo!     // implicit unsafe unwrap
x as! y         // unsafe downcast
optionalValue!  // explicit unsafe unwrap

I want to remove as many as possible of these unsafe expressions from my program, and replace them with safe alternatives.

To remove these unsafe expressions, I first need to identify them. My naive approach so far has been to search for !, and ignore all the false positives like logical negation. What more reliable ways exist? For example:

  • Is there a comprehensive list of all Swift syntax forms which are unsafe? I'm guessing my list above is not comprehensive.
  • Is there an Xcode or compiler flag to turn these operators into compiler warnings or compiler errors?
  • Is there a linter I can run which will do this job?
jameshfisher
  • 34,029
  • 31
  • 121
  • 167
  • @matt thanks - what is that regex? I don't known of a complete list of all syntax forms which are unsafe – jameshfisher Apr 23 '20 at 11:28
  • Also @matt: I tried swiftlint, and it didn't identify these unsafe operators. It complained about a bunch of trivial syntactic problems, but no important semantic problems. Example: it doesn't complain about `URL(string: "")!` – jameshfisher Apr 23 '20 at 11:33
  • Also it just sounds like with swiftlint you forgot to opt in to `force_unwrapping`. – matt Apr 23 '20 at 11:53
  • 1
    I can confirm that SwiftLint does not complain on `let foo = Int("123")!`, even with `// swiftlint:enable force_unwrapping` or `// swiftlint:enable all`. I am not a regular user of that tool though, so I might be overlooking something. – Martin R Apr 23 '20 at 12:01
  • @matt Are you sure that all unsafe operations in Swift follow that pattern? Considering that the list I gave of examples is probably not comprehensive? Force unwrapping is just one example of an unsafe operation – jameshfisher Apr 23 '20 at 12:58
  • 1
    What level of assurance are you trying to reach? All array subscription operations are unsafe, for example. Are you willing to forgo those? *Technically*, every instantiation of a class, closure or protocol existential can crash if the system is out of memory. Further, dynamically dispatched function calls can create infinite (mutual) recursion that blows the stack. – Alexander Apr 23 '20 at 13:06
  • @Alexander-ReinstateMonica a list like that is exactly what I'm looking for! – jameshfisher Apr 23 '20 at 13:17
  • For example, I just discovered `try!`, which is another example of a syntax form which is unsafe, but which is not in my list – jameshfisher Apr 23 '20 at 13:18
  • @jameshfisher But are you now going to try to write Swift without array subscripting, dynamic memory allocation, or (potentially-recursing) dynamic method calls? It's not practical, and Swift's the wrong tool for the job if that's what you're looking for – Alexander Apr 23 '20 at 13:18
  • @Alexander-ReinstateMonica no, I'm not - what I'm looking to do is identify such unsafe operations, then either eyeball it to see whether it's safe, or otherwise, convert to safe operations / add runtime checks – jameshfisher Apr 23 '20 at 13:20
  • @jameshfisher You can't add checks for out-of-memory, and dynamic dispatch makes it impossible (in the general case) to use static call graph analysis to prove there aren't any potentially recursive method call cycles. I would suggest trying to avoid array sub-scripting in most cases, and using a `susbcript(safe index: Int) -> Element?` which returns an optional. – Alexander Apr 23 '20 at 13:22

0 Answers0