4 ms·
How does Swift compare to Rust in safety? I read that Swift is only memory safe in single threaded environments, which is not ideal. I was very enthusiastic ab
by mark_l_watson 4y ago
How does Swift compare to Rust in safety? I read that Swift is only memory safe in single threaded environments, which is not ideal.
I was very enthusiastic about Rust about 4 years ago but decided to learn Swift instead as a new “cool non-Lisp language” to learn. Seeing an recent article on writing Python in Rust made me wish that I had chosen differently.
I found this article made me feel better about security. I expect that increasing use of memory safe languages will lock down public infrastructure and software, making everyone safer.
- tulio_ribeiro 4y agoComparing the Memory Safety of Swift and Rust? When comparing the safety of Swift and Rust, it is important to note that both languages employ strict type systems and compile-time checks to prevent common memory-related bugs such as buffer overflows and access violations. However, the way they handle memory safety in multi-threaded environments differs. In Swift, memory is managed using automatic reference counting (ARC), which tracks and manages the lifetime of objects in order to prevent memory leaks. However, ARC is only effective in single-threaded environments. In a multi-threaded environment, multiple threads can access the same memory simultaneously, which can lead to race conditions and other memory-related issues. In order to avoid these problems in a multi-threaded Swift environment, developers must use synchronization techniques such as locks or atomic operations to ensure that memory is accessed in a safe and predictable way. Rust, on the other hand, uses a borrowing and ownership model to ensure memory safety in both single-threaded and multi-threaded environments. In this model, any value in Rust has a single owner, and the owner is responsible for managing the value's lifetime. When a value is borrowed, the borrower is given a temporary, read-only view of the value, and the original owner continues to be responsible for managing the value's lifetime. This ensures that memory is always accessed in a safe and predictable way, even in a multi-threaded environment. Overall, both Swift and Rust offer strong guarantees of memory safety, but Rust's borrowing and ownership model may provide better guarantees in a multi-threaded environment.
- lalaithion 4y agoI haven't actually been able to find an example program where Swift violates memory safety in a multithreaded environment; I'd love to see an example.
- tulio_ribeiro 4y agoTo clarify, Swift is considered memory safe in single-threaded environments, but additional steps may be necessary to ensure memory safety in multi-threaded environments. This means that if you are writing Swift code that runs on a single thread, you can be confident that it will not suffer from common memory-related bugs. However, in a multi-threaded environment, multiple threads can access the same memory simultaneously, which can lead to race conditions and other memory-related issues. In order to avoid these problems, developers must use synchronization techniques such as locks or atomic operations to ensure that memory is accessed in a safe and predictable way. I hope this helps to clear up any confusion.
- lalaithion 4y agoIt hasn’t, but not because that isn’t a great explanation. I’m not looking for an explanation; I understand the theory. I’m just not super familiar with Swift — I’m looking for an example program that has a (potential) data race which leads to memory y safety.
- saagarjha 4y agoData races in Swift violate memory safety. That’s why you get EXC_BAD_ACCESS crashes from live data out of them.
- lalaithion 4y agoI don't disbelieve this fact; I'd just like to see a sample program that demonstrates it.
- saagarjha 4y ago$ swiftc - import Dispatch var array = [Int]() DispatchQueue.global().async { while true { array.append(Int.random(in: .min...(.max))) } } DispatchQueue.global().async { while true { let range = 0..<array.count guard !range.isEmpty else { continue } array.remove(at: Int.random(in: range)) } } dispatchMain() $ ./main Segmentation fault: 11 $ ./main main(71894,0x16f103000) malloc: double free for ptr 0x13e808200 main(71894,0x16f103000) malloc: *** set a breakpoint in malloc_error_break to debug Abort trap: 6 $