Earlier quoted context omitted.
> As far as I'm aware, if you stay within the confines of smart pointers (and don't drop down to the raw pointer it owns) you will never encounter undefined behavior. Deref'ing an empty (e.g. moved-from) unique_ptr is still UB.
Yeah, there's that. It would be nice if C++ did a emptiness check for you, but I guess that this wasn't in the cards…
A Usable C++ Dialect That Is Safe Against Memory Corruption
61–70 of 103 posts
Re: A Usable C++ Dialect That Is Safe Against Memory Corruption
#62I have a question about this. Articles like http://blog.llvm.org/2011/05/what-every-c-programmer-should-... have convinced me that even if C or C++ reads logically like it is safe, there is a possibility that the compiler can rewrite your code in an acceptable way according to the standards such that the checks that are clearly visible in your code disappear, opening up the very problems that you thought you were pro…
The best thing I've ever encountered that encapsulated this was a Cap'N'Proto vulnerability, and the discussion here about it was enlightening as well.[1] The highly condensed version is that the compiler optimized away an if block that was responsible for throwing an error as impossible to reach in correctly functioning code, when the whole purpose of that if block was to check that condition and error so that the p…
Re: A Usable C++ Dialect That Is Safe Against Memory Corruption
#63Earlier quoted context omitted.
As far as I'm aware, if you stay within the confines of smart pointers (and don't drop down to the raw pointer it owns) you will never encounter undefined behavior. You may have crashes if you try to double free something, but these are defined to crash rather than letting the compiler optimize out checks.
Wouldn't you have a problem with reference cycles in C++ smart pointers? Not sure if they do anything special to prevent this.
Re: A Usable C++ Dialect That Is Safe Against Memory Corruption
#64TL;DR; use smart pointers, RAII semantic and STL containers/iterators. Though, I'd have a few criticism... > Rules to ensure memory safety These "rules" only protect you against object's lifetime issues, not overflow / underflows, and other kind of memory issues. > ‘owning’ pointers are obtained only from operator new no, you shall be using std::make_{unique,shared}(...) which will protect you against leaking memory…
Mostly agree, but: > Don't use C API. The STL should provide you with enough API to use the proper C++ types, either std::string or std::string_view in C++17 if possible. Sometimes you're working with C API that gives you back a char * that they've already allocated. AFAIK there isn't a way to create an std::string out of that without a copy. > you can't static_cast a pointer You can static_cast a void * into other k…
Moreover, you can use static_cast for downcasts (from the parent class to child class) - without runtime costs of dynamic_cast. static_cast is not safe (it doesn't perform runtime checks), but reinterpret_cast is even worse (it doesn't perform even compile-time checks).
Re: A Usable C++ Dialect That Is Safe Against Memory Corruption
#65Earlier quoted context omitted.
The best thing I've ever encountered that encapsulated this was a Cap'N'Proto vulnerability, and the discussion here about it was enlightening as well.[1] The highly condensed version is that the compiler optimized away an if block that was responsible for throwing an error as impossible to reach in correctly functioning code, when the whole purpose of that if block was to check that condition and error so that the p…
-fwrapv should fix it (no warranties of any kind, batteries not included).
There are undoubtedly ways to tell the compiler to be careful, but that isn't always in control of the person writing the code, and even if some level of control exists, compilers change.
Re: A Usable C++ Dialect That Is Safe Against Memory Corruption
#66TL;DR; use smart pointers, RAII semantic and STL containers/iterators. Though, I'd have a few criticism... > Rules to ensure memory safety These "rules" only protect you against object's lifetime issues, not overflow / underflows, and other kind of memory issues. > ‘owning’ pointers are obtained only from operator new no, you shall be using std::make_{unique,shared}(...) which will protect you against leaking memory…
Re: A Usable C++ Dialect That Is Safe Against Memory Corruption
#67This works, although the downside compared to Rust is that soft pointer validity is checked at runtime, meaning that a program that compiles can still randomly fail at runtime and that performance is worse due to the checks. The key idea and massive difference from standard C++ is that object destruction is delayed until a "quiescient state" happens in what is a reframing of RCU [ https://en.wikipedia.org/wiki/Read-c…
Also, the container and mutex tricks you mention sound interesting, but I don’t see why they can’t also be used in C++ (which has a turing complete type system / checker).
Re: A Usable C++ Dialect That Is Safe Against Memory Corruption
#68Earlier quoted context omitted.
int get_value(int* pointer) { return *pointer; } How is a compiler supposed to reject this for undefined behavior? It'd be absurd to demand the compiler someone knows all possible usages for get_value to find if any of them pass a nullptr, so what is it supposed to do? And this is why the spec says things like that deref'ing a null pointer is undefined behavior, so that the compiler can take that function and do the…
The compiler shouldn't rejected UB, it should define all behavior, and reject all code constructs that can't have behavior fully defined (like accessing raw pointers as arrays, so bounds- checking is impossible). It can throw an exception on null de-reference at runtime. That's slow, but safe.
Re: A Usable C++ Dialect That Is Safe Against Memory Corruption
#69Dialects are of limited uses, because they are dialects... New dialects are arguably of even more limited uses, because better languages now exist where the desirable characteristics are enforced not by using a dialect, but by the core languages, and safety checking is not optional. (Also, I'm somewhat curious about why the proposed dialect tells about think "similar to unique_ptr, and so over: just use the real thin…
For me this is the big advantage of C++: it is possible to backport virtually any language feature you want to it, thanks to the combination of modern template programming and low-level C-style bit twiddling.
Re: A Usable C++ Dialect That Is Safe Against Memory Corruption
#70This works, although the downside compared to Rust is that soft pointer validity is checked at runtime, meaning that a program that compiles can still randomly fail at runtime and that performance is worse due to the checks. The key idea and massive difference from standard C++ is that object destruction is delayed until a "quiescient state" happens in what is a reframing of RCU [ https://en.wikipedia.org/wiki/Read-c…
I'd argue that use cases for 'soft pointers' are about the same as that of Rust's RC, which also incurs runtime costs (very briefly - there is no magic here, neither with Rust).
> The key idea and massive difference from standard C++ is that object destruction is delayed until a "quiescient state" happens
If you're speaking about OP - clarification: it is not "object destruction" which is delayed (destructor is still called synchronously when the variable goes out of scope, so all the crazy finalize()-like problems don't occur), it is memory deallocation which is delayed (and this is generally ok as deallocation is not observable, or at least garbage-collected languages tell us so ).
> things like mutexes can only be safe
Whether C++ or Rust or whatever-else, mutexes at app-level are evil ;-) (it can lead to a very long discussion, but long story short - finally, by 2017, most of the opinion leaders started to converge to this IMO-very-obvious observation: ASYNC RULEZZ! ).
> since that allows to statically check for correctness,
The idea behind OP is to have a tool which will do the same thing (where possible, see above re. 'soft pointers' and RC). Whether such a tool materializes - is a different story, but well - first we have to agree that such a tool is a Good Thing(tm).
> have to delay freeing memory
In practice, it is never an observable problem in (Re)Actor-like contexts ((Re)Actor use cases are about highly interactive systems ranging from games to stock exchanges, where typical input is processed in milliseconds, and amount of allocated memory until the 'quiescient state' is reached, is single-digit kilos; in extreme cases, it goes up to single-digit megabytes, still nothing by modern standards).
> you are much better off using Rust
Really really depends. It is still C++, and being C++ has its own virtues (alongside with its own quirks); just two things to illustrate this point - (i) recently it was revealed that modern GPUs are designed with ISO C++ standard in mind (specifically C++, not Rust or anything else); (ii) developer availability is also a major factor for real-world projects, and so on, and so forth. In an ideal world - well, probably Rust does look as a more to-the-point language (though even with Rust I'd create an own dialect, in particular, outlawing thread sync to simplify things), but given real-world considerations - the choice is certainly not that black-and-white.