Originally posted by darkonix
View Post
Originally posted by darkonix
View Post
How does Rust know that the function you execute, which is the "free" function, actually frees the memory? Most functions are black boxes, unless the compiler treats them specially as builtins or with attributes. SInce "free" is a builtin Rust function, it knows that it frees memory allocated by the respective allocator, and so it can give errors on a use-after-free.
But it doesn't know this for arbitrary memory allocation functions, such as from an external library. HeapFree for example. Or some_new_library_free you just wrote. How does it deal with those? It can't. The behavior of the "free" is hardcoded into the compiler.
Note that a lot of builtins for C/C++ are also hardcoded and the compiler emits warnings on misuse! It only does this because it knows the behavior of those functions, they're baked into the compiler proper. It wouldn't know this for external, "black box" APIs.
The simple fix here is easy, and it already exists. Add a compiler attribute to mark such functions. We have __attribute__((__malloc__(...))) for this.
This is obviously not a Rust-specific solution, it works equally everywhere. The only difference is that on C/C++ it might give a warning instead of a flat out error. Not an issue in practice, your code should be clear of warnings to begin with, and if a warning is a false positive, just mask it out selectively where necessary.
Btw, you can use memory allocations now in constexpr code in C++, aka 100% at compiler time, so you can clearly see, that this is not a C++ limitation. The compiler has to special case the allocators since it has to do the entire calculation and evaluation at compile time, including memory allocation and free.
And yes, it's an actual error in constexpr to do use-after-free or to not even free the allocated memory (a memory leak is a flat out error). This goes to show you that, yes, you can detect this stuff at compile time in C++ as well. All it needs is for the compiler to know which functions allocate and which deallocate.
Originally posted by darkonix
View Post
Originally posted by darkonix
View Post
I like C don't get me wrong, but the casts are definitely one of the most dangerous points about it, mostly because of the syntax not being very obvious when reading how dangerous it really can be. I'm not saying unsafe code is bad, don't get me wrong, I love hacks that squeeze out performance in critical areas, but at least make them easy to spot when you debug. And C casts don't have that.
Anyway you can write "safe by default" C++ code in most cases, except for the "move" ctor/assignment op which, imo, should be fixed with an attribute. I still don't understand why GCC or Clang didn't add one yet, while they have one for malloc.
Comment