Live data from Hacker News

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

ithare.com

51–60 of 103 posts

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

#51
post #26

Earlier quoted context omitted.

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.

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

#52
post #28

Earlier quoted context omitted.

Like, the operator ->? Why, and what do you use instead?

You could use ".get()." instead of "->", but I don't see how that helps.

Correction: "(foo)." or smart pointer (foo.get())." instead of "foo->".

But I still don't see how that would help.

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

#53

Earlier quoted context omitted.

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…

> a fundamental misunderstanding of the problem No kidding! There is one right here: > Yes, in some cases the compiler can prove UB, and uses it to write optimiation Compilers do not prove UB , on the contrary they postulate no-UB and then use this axiom to prove other properties of the code.

I suppose that's true, yes. My point was more that your compiler is not hitting a line of code and saying "I know this is or is not UB" because it can not do that in the general case - it is definitely incorrect to say it is 'proving' this. Would you consider that an accurate representation?

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

#54
Dialects 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 think -- at least it would be less a dialect and more of modern standard C++). Dialects enforced by wishful thinking or at beast ad-hoc tools maintained by a too small community will perish in front of well architectured languages maintained by a real community.

They have even been used to ship some important code in big project made of tons of legacy code -- so I'm not even sure an interop argument could be made.

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

#55
post #14

Earlier quoted context omitted.

Wouldn't you have a problem with reference cycles in C++ smart pointers? Not sure if they do anything special to prevent this.

std::weak_ptr is there for resolving reference cycles.

Which means you have to design around it. You can definitely run into problems with cyclical shared_ptr dependencies

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

#56
post #49
post #40

Earlier quoted context omitted.

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.

Would it be possible to write the check so that the null test overlaps with the rest of the instructions? If the test is anyways assumed to pass, you should only get a 1-instruction overhead, right? (That'll only work for null.)

1 instruction != 1 clock cycle. In particular that would utterly kill the usage of unique_ptr on things like small embedded processors or microcontrollers that either lack speculative execution entirely or do not have the level of branch predictor & speculative execution capabilities of a high-end x86 or ARMv8 CPU.

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

#57
This technique is mostly a garbage collector, as I see it. Postponing memory destruction until the stack is empty is a special case of deferred reference counting [1], where sweep can only happen with an empty stack. If the "soft pointers" are implemented with reference counting, that's also a type of GC.

On the other hand, the tagged pointer implementation strategy for "soft pointers" isn't really garbage collection, but it does have much of the same overhead. Pointer reads must check the tag ID and throw, which is like a read barrier [2]. Writes through a pointer must do the same, similar to a write barrier [3]. And that's not getting into the overhead of multithreading; I see no reasonable way to implement this scheme in a multithreaded world. I expect that a fast GC without read barriers will significantly outperform this scheme. As much as everyone complains about the speed of GC, garbage collection is hard to beat!

[1]: http://www.memorymanagement.org/glossary/d.html#term-deferre...

[2]: http://www.memorymanagement.org/glossary/r.html#term-read-ba...

[3]: http://www.memorymanagement.org/glossary/w.html#term-write-b...

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

#58
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…

This is only a problem if you are using threads or shared memory and making up your own misguided locking mechanisms or in embed code on a processor with interrupts but no locks. Normally, if you use the tools correctly you will never have to worry about compiler reordering messing anything up.

The article you linked discusses what happens when you do things you should not, like fail to initialize a variable before using it. Modern compilers, when used correctly will let you know when you do this. With the right compiler options, it won't allow you to make such mistakes.

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

#59
post #55

Earlier quoted context omitted.

std::weak_ptr is there for resolving reference cycles.

Which means you have to design around it. You can definitely run into problems with cyclical shared_ptr dependencies

Well, you have to do this for every language that does reference counting.

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

#60
post #39

Earlier quoted context omitted.

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

std::array has its size fixed at compile time, so there's no reason for you to do have to do bounds checking…
Post reply on HN