Hacker News new | ask | show | jobs
by AnthonyMouse 4450 days ago
> But I should note that memory safety without garbage collection is just hard: it requires the entire language design to be balanced on a delicate precipice.

I was thinking about this recently and I think a large part of the problem is that C arrays are too weakly typed. Array should be a different type than pointer and they shouldn't be convertible. In particular, you shouldn't be able to subscript a pointer, and the in-memory representation of an array should begin with its length. At that point the compiler can include a runtime bounds check for every array access that it can't prove is safe at compile time.

3 comments

Sadly, bounds checking is the easy part; making sure that pointers can't become dangling is the hard one. Unfortunately, use-after-free is an extremely common security vulnerability in the wild (though it wasn't Heartbleed). We solved use-after-free in Rust, at least technically, although there were quite a few tradeoffs we had to make and the usability of the borrow checker is something we're going to need to work on post 1.0.
The more I read about Rust, the more excited I am about it. When I wrote the great-grandparent comment I had Rust in mind.
It isn't hard to do this manually in C, it is just that standard libraries still don't. Partly that is because there is often oneish way to do things that is general and often unsafe and a variety of ways to do things that are safe but more specific to a particular usage pattern. IMO this is also why floating point is popular; it is rarely the best solution to any particular situation but one solution that works ok is often considered better than 10 solutions that work better in partiular cases. Not that this is a good excuse in the case of bounds checking...
>runtime bounds check

The reason people use c, is to get higher speed by avoiding those kinds of checks. A real solution most avoid slowdowns.

If the reason was to avoid those checks, then people really don't know better.

Turbo Pascal => {$R-}

Ada => pragma Suppress (Index_Check);

Modula-3 => cm3 -A

D => dmd -fnoboundscheck / array.ptr[index] in @system code

Just a few examples. Additionally there are lots of research how to remove bounds checking in compiler optimizations

http://citeseer.uark.edu:8080/citeseerx/showciting;jsessioni...

What C has going for it is the symbiotic relationship with UNIX, 40 years of optimizations in most compilers and the historical baggage of being around for so long.

Other better languages suffered from having been shown the door as UNIX spread into the enterprise, but there was a time when C compilers didn't generate better code as the other ones.

You can encode the length of an array in the type in C++, at compile time.