How can you not have memory-safety while also having a garbage collector?
Garbage collection means that all objects live as long as you have a reference to it. Which means that you can only dereference a pointer to invalid memory if you willingly create an invalid pointer, or reinterpret the type of one pointer into another. Going out of bounds of an array counts as the first case.
If a language has garbage collection but no compiler/interpreter supports it, then the language doesn’t have garbage collection.
For a start, having a garbage collector doesn’t mean its use is mandatory, but even in a language where the garbage collector is mandatory, keeping an array alive as long as any references to it exist doesn’t stop you doing things like getting muddled about its length and reading/writing past the end. Mandatory garbage collection only prevents temporal memory bugs like use-after-free, not spatial memory safety bugs like buffer overruns, which need to be prevented by other mechanisms like bounds checks.
As I said, I don’t consider going out of bounds of a buffer a memory safety issue. Forcing the programmer to handle an out-of-bounds case every time there is an array access can be incredibly tedious. So much that not even rust forces you to do so. And if that language has iterators, it’s even less of an issue.
I consider out-of-bounds array access to same as casting a pointer to another type. Just because a language lets you do it, it doesn’t mean that it is not memory safe. It is a performance feature, since checking the bounds every time is always possible (and incredibly easy to implement), but also with too big of an impact when you could just check the length once per loop instead of per loop iteration.
buffer overflows are critical for memory safety since they can cause silent data corruption (bad) and remote code execution (very bad). Compared to those a “clean” unhandled runtime error is far preferable in most cases.
If you’re going to change the definition of words, it’s pretty easy to show that garbage collection on its own is sufficient, but it’s not possible to have a useful conversation if someone’s using their own personal definition of the terms being discussed. The generally accepted definition of memory safety includes deeming out-of-bounds accesses and other spatial memory safety issues unsafe.
With your definition this conversation doesn’t make sense though. Since rust’s direct array access doesn’t perform bounds checks when building in release mode. And it doesn’t require using unsafe.
That’s not what Rust’s documentation says. It does a compile-time bounds check if it can prove what the index might be during compilation, and a runtime bounds check if it can’t. In release mode, it tries harder to prove the maximum index is below the minimum length, but it still falls back to a runtime bounds check if it can’t unless you use get_unchecked, which is unsafe.
How can you not have memory-safety while also having a garbage collector?
Garbage collection means that all objects live as long as you have a reference to it. Which means that you can only dereference a pointer to invalid memory if you willingly create an invalid pointer, or reinterpret the type of one pointer into another. Going out of bounds of an array counts as the first case.
If a language has garbage collection but no compiler/interpreter supports it, then the language doesn’t have garbage collection.
I’ve gotten segfaults in python with only the standard library
For a start, having a garbage collector doesn’t mean its use is mandatory, but even in a language where the garbage collector is mandatory, keeping an array alive as long as any references to it exist doesn’t stop you doing things like getting muddled about its length and reading/writing past the end. Mandatory garbage collection only prevents temporal memory bugs like use-after-free, not spatial memory safety bugs like buffer overruns, which need to be prevented by other mechanisms like bounds checks.
As I said, I don’t consider going out of bounds of a buffer a memory safety issue. Forcing the programmer to handle an out-of-bounds case every time there is an array access can be incredibly tedious. So much that not even rust forces you to do so. And if that language has iterators, it’s even less of an issue.
I consider out-of-bounds array access to same as casting a pointer to another type. Just because a language lets you do it, it doesn’t mean that it is not memory safe. It is a performance feature, since checking the bounds every time is always possible (and incredibly easy to implement), but also with too big of an impact when you could just check the length once per loop instead of per loop iteration.
buffer overflows are critical for memory safety since they can cause silent data corruption (bad) and remote code execution (very bad). Compared to those a “clean” unhandled runtime error is far preferable in most cases.
If you’re going to change the definition of words, it’s pretty easy to show that garbage collection on its own is sufficient, but it’s not possible to have a useful conversation if someone’s using their own personal definition of the terms being discussed. The generally accepted definition of memory safety includes deeming out-of-bounds accesses and other spatial memory safety issues unsafe.
With your definition this conversation doesn’t make sense though. Since rust’s direct array access doesn’t perform bounds checks when building in release mode. And it doesn’t require using unsafe.
That’s not what Rust’s documentation says. It does a compile-time bounds check if it can prove what the index might be during compilation, and a runtime bounds check if it can’t. In release mode, it tries harder to prove the maximum index is below the minimum length, but it still falls back to a runtime bounds check if it can’t unless you use
get_unchecked
, which isunsafe
.