Live data from Hacker News

A Usable C++ Dialect That Is Safe Against Memory Corruption

ithare.com

31–40 of 103 posts

Re: A Usable C++ Dialect That Is Safe Against Memory Corruption

#31
post #4

I 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…

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.

> 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.

No. Even with smart pointers it's possible (move out of unique_ptr, deref). But even with no pointers it's possible - index into an array without checking the bound, signed int overflow, etc.

Re: A Usable C++ Dialect That Is Safe Against Memory Corruption

#32
post #4

I 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 generally recommended thing for catching & fixing this is: https://clang.llvm.org/docs/UndefinedBehaviorSanitizer.html

CppCon has also had a lot of great talks on UB and why it is what it is, such as https://www.youtube.com/watch?v=yG1OZ69H_-o

Re: A Usable C++ Dialect That Is Safe Against Memory Corruption

#33
post #26
post #10

Earlier quoted context omitted.

Perhaps someone better versed in those compilers can add to/correct me here, but I'm pretty sure that can only happen if you're invoking UB somewhere along the line.

That's exactly the problem. C/C++ has undefined behavior as part of the language spec, so it can never be safe unless you use a compiler that promises to reject programs that invoke undefined behavior.

It's more complicated than this. C++ compilers can't just "reject" UB code - they don't have enough information at all times to prove that code invokes UB, the languages is not powerful enough to represent this in all cases.

When people say "just fix this in compilers, don't compile when they run into UB" it's a fundamental misunderstanding of the problem. Yes, in some cases the compiler can prove UB, and uses it to write optimiations, but it doesn't prove that all code is not invoking UB.

Re: A Usable C++ Dialect That Is Safe Against Memory Corruption

#34
This 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-copy-update], allowing to freely use raw pointers as long as none survive across a quiescient state.

[note however that this system allows to take pointers to stack variables, so they have to restrict raw pointers to function arguments only - it would be better to also introduce a "heap-only" pointer that can be freely returned/stored on the heap/etc. but can't be stored in types that live across a quiescient state, from which stack-or-heap raw pointers can be derived]

This also results in the downside that things like mutexes can only be safe if they are kept locked until a quiescient state happens, since that's the only lifetime that the system understands.

Likewise, you can't do this like prevent updating a collection while iterating unless you are fine with freezing the collection until a quiescient state happens.

In general, you are much better off using Rust (or an equivalently expressive language, if it existed), since that allows to statically check for correctness, not have to delay freeing memory, and allows to use lifetimes and linear types to secure mutex locking, collection iteration, and other things where lifetimes are essential.

Re: A Usable C++ Dialect That Is Safe Against Memory Corruption

#35
post #8

TL;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…

>AFAIK there isn't a way to create an std::string out of that without a copy.

You can use std::string_view, Google's StringPiece or llvm::StringRef.

Re: A Usable C++ Dialect That Is Safe Against Memory Corruption

#39
post #8

TL;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…

> Do you mean std::vector and at()?

No, std::array was added in C++11: http://en.cppreference.com/w/cpp/container/array

Re: A Usable C++ Dialect That Is Safe Against Memory Corruption

#40

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…

Then you have a check on every deref, which means you incur a relatively large performance penalty for using a smart pointer. If you want stuff like this there are other languages out there.
Post reply on HN