Live data from Hacker News

Why Safety Profiles Failed

circle-lang.org

141–150 of 233 posts

Re: Why Safety Profiles Failed

#141

Earlier quoted context omitted.

> But not everyone is interested in introducing a second toolchain, for example. Not that this invalidates your broader point about Safe C++, but this particular issue could also be solved by Rust shipping clang / a frontend that can also compile C and C++.

On the one hand, I think that it would be a winning strategy. On the other, that effectively turns C++ part of the Rust language. And that is even before looking at the need to extend the Rust compiler to express things that the Rust language doesn't have/need but C++ does, like move constructors.

I don’t see how it would make C++ part of the language. Nothing in the Rust front end would need to know about C++. It’s a sub command that would passthrough clang.

If you were worried about clang flag stability not being as stable as Rust, you could also include clang as part of llvm-tools. This would add an extra step to set up, but is still easier than today.

Of course, in both cases there’s still the work of having rust up (or rustc, depending on the strategy) set up the sysroot. I’m not saying this is trivial to do, but it would make cross compilation so much better than today, and bring rust to parity with Zig and Go on this front.

Re: Why Safety Profiles Failed

#142
post #87

> A C++ compiler can infer nothing about aliasing from a function declaration. True. but you don't solely rely on the declaration, do you? lots of power comes from static analysis.

It’s important to only rely on the declaration, for a few reasons. One of the simpler ones is that the body may be in another translation unit.

Re: Why Safety Profiles Failed

#143
post #17

Earlier quoted context omitted.

> "No mutable aliases" is a mistake; it prevents many useful programs. Does it? You didn't list any. It certainly prevents writing a tremendous number of programs which are nonsense.

The entirety of Rust's `std::cell` is a confession that yes, we really do need mutable aliases. We just pretend they the aliases aren't mutable except for a nanosecond around the actual mutation.

And Rc is a "confession" that we still need reference counting semantics. And macros are a "confession" that pure Rust code isn't powerful enough. And "unsafe" is a "confession" that we really do need "unsafe". And so on and so forth with all kinds of features.

Except that's a really harsh and unproductive way to phrase it. The existence of "unsafe" is not a "confession" that safe code is impossible so why should even try.

Progress in safety is still made when an unsafe capability is removed from the normal, common, suggested way to do things and it is moved to something you need to ask for and take responsibility for, and hemmed in by other safe constructs around it.

Re: Why Safety Profiles Failed

#144
post #117

Earlier quoted context omitted.

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?

It’s not open source. The GitHub activity is purely for documentation.

I don’t know about real world adoption, nor do I think it’s really about what I’m saying. The proposal was made public a few weeks ago. There hasn’t been much time for real world projects to adopt it, if that were even the goal. The point is that it does exist today, and you can try it out. It’s more than just a design on paper.

Re: Why Safety Profiles Failed

#145
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 ==…

one day we will bring segments and far pointers back.

Re: Why Safety Profiles Failed

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

> When a pointer comes from unchecked code, it is assumed to be valid.

It certainly helps, but is not a full solution.

Re: Why Safety Profiles Failed

#147
post #90

I'm confused over lines such as "Profiles have to reject pointer arithmetic, because there’s no static analysis protection against indexing past the end of the allocation." Can't frama-c/etc do that? Additionally, section 2.3 is narrower than what is implied by the words "safe" and "out-of-contract" and is more concerned with what C/C++ call "undefined behavior" requirements than contract correctness. Ie. An integer…

You cannot cause undefined behavior with integer overflow using + in Rust. That behavior is considered an error, but is well defined.

Re: Why Safety Profiles Failed

#148

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

"Whole-program analysis is not tractable (i.e., not scalable),"

The search term for those who'd like to follow up is "Superoptimization", which is one of the perennial ideas that programmers get that will Change the World if it is "just" implemented and "why hasn't anyone else done it I guess maybe they're just stupid", except it turns out to not work in practice. In a nutshell, the complexity classes involved just get too high.

(An interesting question I have is whether a language could be designed from the get-go to work with some useful subset of superoptimizations, but unfortunately, it's really hard to answer such questions when the bare minimum to have a good chance of success is 30 years of fairly specific experience before one even really stands a chance, and by then that's very unlikely to be what that person wants to work on.)

Re: Why Safety Profiles Failed

#149
post #66

Earlier quoted context omitted.

From P3465: "why this is a scalable compile-time solution, because it requires only function-local analysis" From P1179: "This paper ... shows how to efficiently diagnose many common cases of dangling (use-after-free) in C++ code, using only local analysis to report them as deterministic readable errors at compile time." Local analysis only. It's not looking in function definitions. Whole program analysis is extremel…

Making programmers manually annoate every single function is infinitely more costly.

Are you also a proponent of nonlocal type inference? Do you think annotating types is too costly for programmers?

Re: Why Safety Profiles Failed

#150
post #133

Additionally I still cannot understand why they didn't make iterators safe from the very beginning. In the alias examples some iterators must alias and some not. With safe iterators the checks would be trivial, as just the base pointers need to be compared. This could be done even at compile-time, when all iterators bases are known at compile-time. Their argument then was that iterators are just simple pointers, not…

We're talking about a commitee that still releases "safety improving" constructs like std::span without any bounds checking. Don't think about it too much.
Post reply on HN