Live data from Hacker News

Why Safety Profiles Failed

circle-lang.org

111–120 of 233 posts

Re: Why Safety Profiles Failed

#111
post #44

Earlier quoted context omitted.

This seems to be a common theme with many c++ developers honestly.

Most C++ devs don't care that much either way I'd say, it's a vocal minority that does. I really don't understand the nay-sayers though, been a C++ dev for over 15 years, I'd give an arm and a leg for 1. faster language evolution (cries in pattern matching) and 2. a way to enforce safe code. Having to use std::variant when I want to use a sum type in 2024 is just so backwards it's hard to express. Still love the lang…

C++ became my favourite language after Object Pascal, as it provided similar safety levels, added with the portability.

I never been that big into C, although I do know it relatively well, as much as anyone can claim to do so, because it is a key language in anything UNIX/POSIX and Windows anyway.

One of the appealing things back then were the C++ frameworks that were provided alongside C++ compilers, pre-ISO C++98, all of them with more security consideration than what ended up landing on the standard library, e.g. bounds checking by default on collection types.

Nowadays I rather spend my time in other languages, and reach out to C++ on a per-need basis, as other language communities take the security discussion more seriously.

However, likewise I still love the language itself, and is one of those that I usually reach for in side projects, where I can freely turn to 100% all the safety features available to me, without the usual drama from some C++ circles.

Re: Why Safety Profiles Failed

#112
post #46

Earlier quoted context omitted.

The borrow checker works irrespective of the heap. Memory safety involves all pointers, not just ones that own a heap allocation.

If we're trying to minimize annotation while maximizing C compatibility, it will be necessary to heap-allocate stack frames. This cost can be mitigated with annotations, once again. In this case, a global "forbid leaks even if unused" flag would cover it. Static allocations only need full heap compatibility if `dlclose` isn't a nop. And TLS is the forgotten step-child, but at the lowest level it's ultimately just imp…

> it will be necessary to heap-allocate stack frames.

I sure hope you don't use any stack frames while writing the stack frame allocator.

Re: Why Safety Profiles Failed

#113
post #94

Earlier quoted context omitted.

Not everything will be rewritten in Rust. I've broken down the arguments for why this is, and why it's a good thing, elsewhere [1]. Google's recent analysis on their own experiences transitioning toward memory safety provide even more evidence that you don't need to fully transition to get strong safety benefits. They incentivized moving new code to memory safe languages, and continued working to actively assure the…

Nah. The idea that sustained bugfixing could occur on a project that was not undergoing active development is purely wishful thinking, as is the idea that a project could continue to provide useful functionality without vulnerabilities becoming newly exposed. And the idea of a meaningfully safer C++ is something that has been tried and failed for 20+ years. Eventually everything will be rewritten in Rust or successor…

> Nah.

I know it's intended just to express disagreement, but this comes across as extremely dismissive (to me, anyway).

Re: Why Safety Profiles Failed

#114
post #91

Earlier quoted context omitted.

How would this fix memory safety issues like std::sort(vec1.begin(), vec2.end()) (where vec1 and vec2 are different vectors, of course)? Or strlen(malloc(100))?

With a safe runtime, a pointer is really something like a `struct { u32 allocation_base, allocation_offset;}`. (it may be worth doing fancy variable-bit-width math to allow many small allocations but only a few large ones; it's also likely worth it to have a dedicated "leaf" section of memory that is intended not to contain any pointers) An implementation of `sort` would start with: `assert (begin.allocation_base ==…

Tracking allocations is necessary, but not sufficient.

  struct S {
    int arr1[100];
    std::string s;
    int arr2[100];
  };

  void foo(S& s) {
    //arr1 and arr2 are in the same complete object
    //so they are in the same allocation
    std::sort(std::begin(arr1), std::end(arr2));
  }
To make it sound you really need to track arrays specifically (including implicit single-element ones), not just allocations.

It's surely somewhat feasible, as the constexpr interpreters in compilers do track it, but something like that would probably be way inefficient at runtime.

Re: Why Safety Profiles Failed

#116

At this point I'm wondering if the purpose of safety profiles is simply to serve as a distraction. In other words, safety profiles are just something people can point to when the topic of memory safety comes up, that’s it. The objectives of the initiative always seemed hopelessly optimistic, if not absurd. In particular, I don't understand why littering a codebase with auto, const, constexpr, inline, [[nodiscard]], n…

I think maybe it's because lifetime annotations can get arbitrarily complicated. If you look at enough Rust code you'll definitely see some function signatures that make your head hurt, even if they're vastly outnumbered by simple ones. A guarantee that the comprehension complexity of that part of your code will always be below some low ceiling is tempting.

Yes. Lifetimes are complicated. Complicated codes make them even harder.

Not annotating is not making anything easier.

Re: Why Safety Profiles Failed

#117
post #47

What actually is this circle-lang site, and who runs it? The main page seems to just redirect to example.com, and I don't recognize the name of the author.

Circle is a C++ compiler by Sean Baxter, with various extensions. One of those is an implementation of the Safe C++ proposal I’ve linked downthread.

Does the Circle compiler see any real-world use? I keep hearing about it, but it seems like it is a one-person project which hasn't seen significant activity in about a year.

On paper it does sound quite promising, but looking at the Github repo I can't help but shake the feeling that it is more talk than action. It seems to have basically been abandoned before it ever saw any adoption?

Re: Why Safety Profiles Failed

#118
post #94

Earlier quoted context omitted.

Nah. The idea that sustained bugfixing could occur on a project that was not undergoing active development is purely wishful thinking, as is the idea that a project could continue to provide useful functionality without vulnerabilities becoming newly exposed. And the idea of a meaningfully safer C++ is something that has been tried and failed for 20+ years. Eventually everything will be rewritten in Rust or successor…

> The idea that sustained bugfixing could occur on a project that was not undergoing active development is purely wishful thinking yet the idea that a project no longer actively developed will be rewritten in rust is not?

> yet the idea that a project no longer actively developed will be rewritten in rust is not?

Rewriting it in Rust while continuing to actively develop the project is a lot more plausible than keeping it in C++ and being able to "maintain a stable codebase" but somehow still fix bugs.

(Keeping it in C++ and continuing active development is plausible, but means the project will continue to have major vulnerabilities)

Re: Why Safety Profiles Failed

#119
post #7

"No mutable aliases" is a mistake; it prevents many useful programs. Now that virtual address space is cheap, it's possible to recompile C (or presumably C++) with a fully-safe runtime (requiring annotation only around nasty things like `union sigval`), but this is an ABI break and has nontrivial overhead (note that AddressSanitizers has ~2x overhead and only catches some optimistic cases) unless you mandate addition…

The tinyCC compiler, written by fabrice bellard, has a feature that enables pointer checking and makes the resulting C code safe.

Re: Why Safety Profiles Failed

#120

The assumption here seems to be that the compiler/analyzer is only able to look at one function at a time. This makes no sense. Safety is a whole-program concern and you should analyze the whole program to check it. If anything as simple as the following needs lifetime annotations then your proposed solution will not be used by anyone: const int& f4(std::map & map, const int& key) { return map[key]; }

Whole-program analysis is not tractable (i.e., not scalable), and Rust has already proven that function signatures are enough, and does actually scale. The analysis can be performed locally at each call site, and doesn't have to recurse into callees.

Your function would look like this in Rust:

    fn f4(map: &'a Map, key: &i32) -> &'a i32 { ... }
You don't need much more than a superficial understanding of Rust's lifetime syntax to understand what's going on here, and you have much more information about the function.
Post reply on HN