Live data from Hacker News

Making C++ safe without borrow checking, reference counting, or tracing GC

verdagon.dev

161–170 of 226 posts

Re: Making C++ safe without borrow checking, reference counting, or tracing GC

#161
post #98

Earlier quoted context omitted.

This would be true if code using the borrow checker was easier to read than to write.

I think it’s generally accepted that writing code is nearly universally easier than reading code, in any language. That aside, getting a mechanical check on memory safety for the price of some extra language verbosity is obviously worth it IMO. By the same token, it is common to see criticisms of the complexity of templates in C++, but templates are the cornerstone of “Modern C++” and many libraries could not exist w…

> getting a mechanical check on memory safety for the price of some extra language verbosity is obviously worth it IMO

But a GC'd language doesn't require the extra verbosity.

Re: Making C++ safe without borrow checking, reference counting, or tracing GC

#162
post #63

Methods such as these for C and C++ are interesting, and needed, but only solve a part of the problem. As others have noted before, they do little good because they're opt-in. I think there's a bit of nuance to that which needs to be explored though, as I think it's less a problem that the extra checks are opt in, and more a problem of how we use and categorize libraries. As long as we encourage dynamic and static li…

Often missed here is that the Rust library author is strongly protected from faulty code written by Users. The C/C++ library author is not.

The most obvious examples of this are memory allocation. The C/C++ user claimed the buffer was large enough to contain the result. The Rust user received back an object that protected the memory and returned it at the right time.

But it could also be a file handle or mutex that used the Rust ownership patterns to protect the underlying data.

If I am using a library and the author can put in features that prevent misuse, I don't need to work so hard to use the library correctly. As soon as my safe code compiles I can be fairly sure with most rust libraries that I didn't break some unenforced rule.

Re: Making C++ safe without borrow checking, reference counting, or tracing GC

#163
post #19

The reason why safety in C++ is difficult to achieve is due to the memory model used by C and C++. The memory model is a flat space provided by the OS that can be addressed by pointers. In this sense, C++ is similar to assembly code. A language like Java, on the other hand, assumes a different model where you can only access objects with well defined behavior. To change this, one needs to disallow the use of native p…

That's pretty much what the article says though. "Don't use traditional pointers" is a fairly trivial rule to enforce via static analysis, and constructs like unique_ptr are syntactically identical anyway. The bit that has me confused is that it's inventing a new term, "borrowing affine style", to describe a longstanding paradigm that has traditionally been called "RAII". Now, neither term is very clear, but surely i…

Affine in this case is referring to not being able to use values after they have been moved. When I say not able to use, I mean that it's a compile time error to attempt to use them.

C++ does not restrict you from using things after they have been moved and therefore does not have affine typing!

Re: Making C++ safe without borrow checking, reference counting, or tracing GC

#164

Earlier quoted context omitted.

I think it’s generally accepted that writing code is nearly universally easier than reading code, in any language. That aside, getting a mechanical check on memory safety for the price of some extra language verbosity is obviously worth it IMO. By the same token, it is common to see criticisms of the complexity of templates in C++, but templates are the cornerstone of “Modern C++” and many libraries could not exist w…

> getting a mechanical check on memory safety for the price of some extra language verbosity is obviously worth it IMO But a GC'd language doesn't require the extra verbosity.

And you pay for that in performance

Re: Making C++ safe without borrow checking, reference counting, or tracing GC

#165
post #62

Earlier quoted context omitted.

Yes it’s really undefined. There is a distinction from “implementation defined behavior” which you seem to be confusing it with. You are practically wrong in your assumptions. Since undefined behavior is undefined the compiler is free to do anything with compilation, it may compile to something but you have no guarantee what that something is. And in real life this often actually bites you when the optimizer comes in…

No; this is a common misconception I see from people who swallowed the "it's allowed to format your hard drive and blow up your monitor" dodge vs. the electrical engineers who know where terminology like 'undefined behavior' originated in engineering. In practice, it tends to do something subtle and usually right but probably wrong for the simple, practical reason that if it did anything as obviously wrong as "format…

[deleted]

Re: Making C++ safe without borrow checking, reference counting, or tracing GC

#166
post #62

Earlier quoted context omitted.

Yes it’s really undefined. There is a distinction from “implementation defined behavior” which you seem to be confusing it with. You are practically wrong in your assumptions. Since undefined behavior is undefined the compiler is free to do anything with compilation, it may compile to something but you have no guarantee what that something is. And in real life this often actually bites you when the optimizer comes in…

No; this is a common misconception I see from people who swallowed the "it's allowed to format your hard drive and blow up your monitor" dodge vs. the electrical engineers who know where terminology like 'undefined behavior' originated in engineering. In practice, it tends to do something subtle and usually right but probably wrong for the simple, practical reason that if it did anything as obviously wrong as "format…

> No; this is a common misconception I see from people who swallowed the "it's allowed to format your hard drive and blow up your monitor" dodge vs. the electrical engineers who know where terminology like 'undefined behavior' originated in engineering.

You are arguing against topics I never brought up. (I am an EE fwiw). I have no misconceptions where undefined behavior comes from and have demonstrated none thus far.

> This is why I actually hate using this programming language, because when you hit undefined behavior (which the language makes trivial to do)

Ok so you want to editorialize on something else entirely.

No idea how that dismisses anything I said or referred to.

Regardless of how trivial it is in practice to invoke undefined behavior it doesn’t change the real differences between undefined and implementation defined behavior.

Re: Making C++ safe without borrow checking, reference counting, or tracing GC

#167
post #166

Earlier quoted context omitted.

No; this is a common misconception I see from people who swallowed the "it's allowed to format your hard drive and blow up your monitor" dodge vs. the electrical engineers who know where terminology like 'undefined behavior' originated in engineering. In practice, it tends to do something subtle and usually right but probably wrong for the simple, practical reason that if it did anything as obviously wrong as "format…

> No; this is a common misconception I see from people who swallowed the "it's allowed to format your hard drive and blow up your monitor" dodge vs. the electrical engineers who know where terminology like 'undefined behavior' originated in engineering. You are arguing against topics I never brought up. (I am an EE fwiw). I have no misconceptions where undefined behavior comes from and have demonstrated none thus far…

Every undefined behavior is de facto implementation-defined because something happens resulting from the state of the machine and the code being executed. Change the implementation and the thing that happens changes.

(I know the c++ spec defines these terms differently; I'm not talking about the spec definitions and I never was. I'm saying the spec definitions are a dodge around what actually happens when code is compiled and executed).

Re: Making C++ safe without borrow checking, reference counting, or tracing GC

#168
post #166

Earlier quoted context omitted.

> No; this is a common misconception I see from people who swallowed the "it's allowed to format your hard drive and blow up your monitor" dodge vs. the electrical engineers who know where terminology like 'undefined behavior' originated in engineering. You are arguing against topics I never brought up. (I am an EE fwiw). I have no misconceptions where undefined behavior comes from and have demonstrated none thus far…

Every undefined behavior is de facto implementation-defined because something happens resulting from the state of the machine and the code being executed. Change the implementation and the thing that happens changes. (I know the c++ spec defines these terms differently; I'm not talking about the spec definitions and I never was. I'm saying the spec definitions are a dodge around what actually happens when code is com…

I have no idea what your thesis is.

It seems to me that you’re claiming that the existence of undefined behavior is bad. Which isn’t actually that controversial outside of certain people weirdly infatuated with C/C++.

But it seems moreover you merely have a problem with it being called undefined behavior or something, as if the word itself isn’t harsh enough.

I don’t see it. I don’t see the problem with the definitions as stated. It doesn’t weaken any commentary about undefined behavior to me at least.

And again regardless of your hatred for C++ weenies it doesn’t change the fact that there are meaningful practical differences between undefined and implementation defined behavior, the distinction has to exist regardless of what you call them.

> Every undefined behavior is de facto implementation-defined because something happens resulting from the state of the machine and the code being executed.

Regardless of spec this makes no sense to me. Implementation defined implies something is still “defined”, like not in the spec but somewhere. Undefined means what it says - it’s undefined.

I don’t even disagree with your other points but I don’t get how complaining about the practical difficulties of avoiding undefined behavior have to do with a “definitions dodge”

Re: Making C++ safe without borrow checking, reference counting, or tracing GC

#169
post #111

Earlier quoted context omitted.

Sure but you're missing the > so long as you are diligent about checking invariants part. Could you go through and check all the parts of a huge C++ codebase to make sure invariants are held as opposed to a few hundred lines of unsafe Rust code?

Sure, but I think the point here is the degree. Presumably if it takes a lot of unsafe rust lines to build something, it won’t matter if it’s 30% safe or whatever. I just see the point of “unsafe is fine” a lot when the whole point of rust is that memory safety issues are never worth the cost.

Looking at a couple of programs I work on:

9,500 lines of code, 8 are unsafe.

7,000 lines of code, 22 are unsafe.

14,000 lines of code, 140 are unsafe.

As we follow the standard rust rule that "safe code should not be able to use unsafe code to do unsafe things", those unsafe bits of code have been very carefully checked, to the best of our abilities, to ensure they don't create memory safety issues. It is a lot easier to triple-check 170 lines of code than 30,000 lines.

Post reply on HN