Live data from Hacker News

Some Were Meant for C: The Endurance of an Unmanageable Language [pdf]

cl.cam.ac.uk

71–80 of 253 posts

Re: Some Were Meant for C: The Endurance of an Unmanageable Language [pdf]

#71

Earlier quoted context omitted.

> They may not be "sane" in your view because they're different from the way you implement them in C++ I saw two kinds of Rust graphs. One is safe, easy to understand, but slow (e.g. reference counting). Another one (unsafe Rust) is very hard to implement, thousands lines of code. Also, modern C++ is much safer than unsafe rust. > C++ has no protection against the most pernicious memory management errors, particularl…

I can't reply directly to your other comment, so I'll do it here. In the case of pet-graph, I wouldn't say it has large amounts of unsafe (I reviewed it recently b/c I might start using it), but it does use unsafe. Most data structures in Rust require unsafe for performance or memory access patterns. In these cases the developer is the one responsible for guaranteeing that it is safe (no loss over an unsafe language)…

> I can't reply directly to your other comment

Next time just wait 5-10 minutes.

> Most data structures in Rust require unsafe for performance or memory access patterns.

And when I want to compose 2 data structures into my own higher-level one, for performance and memory access patterns I need these two lower-level structures to expose unsafe stuff at their API boundaries. The data structures I saw don’t do that, they’re designed to be consumed from safe Rust instead.

> Rust doesn't just throw out all the rules

I think in modern C++, with these iterators and smart pointers, you’re less likely to screw up dereferencing a wrong pointer.

Re: Some Were Meant for C: The Endurance of an Unmanageable Language [pdf]

#72
post #46

Earlier quoted context omitted.

> All I can say is that the reaction to Cargo from Rust programmers is overwhelmingly, almost universally positive You can prove anything when you introduce a sampling bias that large. > Not solving builds and package management is not a realistic option for a language in 2017. Package management was solved decades ago, my OS manages the packages and a lean and mean system is the result. The rust solution results in…

Many existing Rust users were extremely skeptical when Cargo was announced, many said they'd stick with Makefiles. In the end, they didn't. > Package management was solved decades ago If it was, there wouldn't be new package managers popping up all the time; it's a non-trivial problem. They're not created for no reason. > The rust solution results in massive binary sizes for simple command line tools. This isn't exac…

That's a great point: we effectively tried the "just use Makefiles" solution already. It failed.

Re: Some Were Meant for C: The Endurance of an Unmanageable Language [pdf]

#73
You can pry gcc out of my cold, dead hands when your fancy type-safe high level languages will let me do things like:

* Fork a running program to enable analysis or serialisation of program state without blocking, or

* Use mmap to allocate all my datastructures on disk, or

* Have full control over what happens when my program receives a signal, or

* exec another program but have it to inherit all the open file descriptors and network connections, or...

Re: Some Were Meant for C: The Endurance of an Unmanageable Language [pdf]

#74
post #60

Earlier quoted context omitted.

> They may not be "sane" in your view because they're different from the way you implement them in C++ I saw two kinds of Rust graphs. One is safe, easy to understand, but slow (e.g. reference counting). Another one (unsafe Rust) is very hard to implement, thousands lines of code. Also, modern C++ is much safer than unsafe rust. > C++ has no protection against the most pernicious memory management errors, particularl…

> I saw two kinds of Rust graphs. There's a third kind, which uses indexes into arrays containing the nodes and edges, instead of direct pointers to the node/edge. > CRT debug heap / MALLOC_CHECK_ / libefence, depending on the platform/compiler Can any of these protect against the scenario where a block of memory is freed, allocated again for another purpose, but still accessed through the old dangling pointer? Also,…

> There's a third kind, which uses indexes into arrays containing the nodes and edges

Pointers are still faster. Also with arrays it’s expensive to reduce RAM usage after a lot of nodes were removed.

> Can any of these protect against the scenario where a block of memory is freed, allocated again for another purpose, but still accessed through the old dangling pointer?

No 100% guarantee, but AFAIR CRT debug heap takes measures to reduce RAM reuse when it can.

> are they always present at runtime, or are they used only on debug builds

Not present. Yes, only on debug builds. Still, these early debug traps are quite helpful while development.

Re: Some Were Meant for C: The Endurance of an Unmanageable Language [pdf]

#75
post #42

Earlier quoted context omitted.

Following the logic of the article, Rust has made the exact same mistake every other language has made, which is to conceptualize compatibility with the C ecosystem has merely an issue FFI. Rust is hardly the first language to focus on easy FFI from day 1, but according to the article that's not nearly sufficient. And like most other modern so-called systems language, Rust hasn't gotten around to committing to a stab…

> And like most other modern so-called systems language, Rust hasn't gotten around to committing to a stable, exportable ABI. That's not true. The C ABI is stable and exportable, and you can opt into it on a per-function basis. We do that for integration with existing projects all the time. Again: All of you are talking as though the idea of integrating Rust into a large C++ project is some far-fetched theoretical id…

I'm not arguing that it's too difficult integrate Rust with C or C++ projects. I'm simply trying to get at the distinctions that the article is making, which are rather subtle.

One aspect of Rust that fits well, IMO, with the characteristics the article argues are under appreciated is its emphasis on POD--objects as compact, flat bytes. That puts Rust much closer to achieving what C does best (again, according to the article), which is first-class syntactic constructs over memory--namely, pointers. But it falls short in the sense that to _export_ Rust objects (rather than import alien objects into Rust) you have to do so explicitly. And presumably the author would argue that Rust is significantly undervaluing the benefit of a stable ABI that would allow other applications to import Rust objects without an explicit language-level construct (i.e. explicitly annotating APIs with no_mangle).

Obviously when you're building a large application, cathedral style, the requirement to explicitly annotate is not only less burdensome, but quite useful (for many reasons). But in a larger, heterarchical ecosystem of software, that's actually quite limiting. Our first instinct is to argue that permitting such unintended peeking behind the curtain is dangerous and unnecessary, but the article speaks directly to that.

Imagine a Rust with a stable ABI that was exported via Sun's CTF format. CTF is like DWARF but much simpler (and thus little incentive to strip it), and it's being integrated into both OpenBSD and (I think) FreeBSD to facilitate improved dynamic linking infrastructure. Rust could even, theoretically, continue randomizing member fields. And this data could be consumed by any language's toolchain, not simply Rust's toolchain. That sort of language-agnostic, holistic approach to interoperability is largely what I think the article is getting at.

Re: Some Were Meant for C: The Endurance of an Unmanageable Language [pdf]

#76
post #66

Earlier quoted context omitted.

When I checked out Rust a year ago, I immediately discovered it has no SIMD (SSE, AVX, Neon). That it has no sane ways to implement a graph structure. Also that it’s hard to compose data structures into higher-level specialized ones. Also, I highly encourage people who worry about pointer management all the time to checkout modern C++.

When I checked out rust a year ago, I tried to implement three things: - Some OT code. This went ok, but I still have no idea which of the 6 string types I should use for a library like that. I think I ended up settling for Rc > or something, but it still wasn't ideal. Swift, Go and C all each have a canonical string type. - First I tried to make a skip list with performance matching the performance of my C implement…

> This went ok, but I still have no idea which of the 6 string types I should use for a library like that. None of Swift, Go or C have this problem.

There are two string types: a string that owns its contents and a string that references its contents. This is the same as in any language that uses smart pointers for resource management.

Can you name a string type that you think should be removed, and explain why?

> First I tried to make a skip list with performance matching the performance of my C implementation. I discovered that even with unsafe there was no way to make a struct with a dynamically sized array at the end, like I can easily do in C.

Yes, you can. You can make a one element array and allocate and deallocate manually, just as you do in C. The offset method on pointers allows for arbitrary pointer arithmetic.

> Despite all the hype, adding a dynamic item to the event bus didn't work because it wasn't 'static didn't work.

I haven't used Tokio, but couldn't you use a boxed trait?

Re: Some Were Meant for C: The Endurance of an Unmanageable Language [pdf]

#77

Earlier quoted context omitted.

I've used both C and Pascal in embedded systems. Pascal is painful compared to C. A "somewhat modified" version might help, but I doubt it would be enough. To steal a phrase from my friend Michael Pavlinch: Pascal was like picking your nose with boxing gloves on. A modified boxing glove isn't really going to solve the problem. For that matter, once we weren't on Unix but rather on the PC, and we had a nicely-modified…

> For that matter, once we weren't on Unix but rather on the PC, and we had a nicely-modified Pascal (Turbo Pascal), why did C/C++ win there, too? Turbo Pascal was quite successful in its day. But Microsoft chose C, and the rest is history. Absent Microsoft's decision, Pascal might still be around. If you look at early Mac development, for instance, Pascal was actually preferred. C only ended up winning due to being…

> Pascal might still be around.

Well that's a bit rude. Pascal is still around! And I love it. Behold:

https://www.freepascal.org/

https://www.embarcadero.com/products/delphi

Re: Some Were Meant for C: The Endurance of an Unmanageable Language [pdf]

#78
post #57

Earlier quoted context omitted.

> That it has no sane ways to implement a graph structure. Sure it does. I work with graphs in Rust all the time. They may not be "sane" in your view because they're different from the way you implement them in C++, but I could equally well say that there's no "sane" way to implement a safe owning pointer in C++ (since there's no memory-safe way to do so). > Also, I highly encourage people who worry about pointer man…

> I could equally well say that there's no "sane" way to implement a safe owning pointer in C++ unique_ptr + std::move gives you that semantically. Sure it won't stop you from dereferencing a null pointer but, in all the years i've been writing C++, finding and fixing null pointer dereferences wouldn't rank very high on my list of things to worry about. They always kill your program and are easy to spot in an IDE or…

Unique pointers provide no protection against use after free, because you can take a reference to their contents and that reference can become dangling. Because the destructor of a unique pointer is invoked automatically per the language rules, as opposed to in C where an explicit call to free is required, this makes C++ more prone to UAF than C.

Re: Some Were Meant for C: The Endurance of an Unmanageable Language [pdf]

#79
First class communication as a feature. Notice that many of the more popular languages value the ability to link to C libraries. Most languages have a way to call (or even statically link) external C code. It's not as easy to do the same with other languages because they lack this ease of interfacing. It's easy in C because it's low level, everything is plain old data and function pointers.

Re: Some Were Meant for C: The Endurance of an Unmanageable Language [pdf]

#80

Earlier quoted context omitted.

> That it has no sane ways to implement a graph structure. Sure it does. I work with graphs in Rust all the time. They may not be "sane" in your view because they're different from the way you implement them in C++, but I could equally well say that there's no "sane" way to implement a safe owning pointer in C++ (since there's no memory-safe way to do so). > Also, I highly encourage people who worry about pointer man…

> They may not be "sane" in your view because they're different from the way you implement them in C++ I saw two kinds of Rust graphs. One is safe, easy to understand, but slow (e.g. reference counting). Another one (unsafe Rust) is very hard to implement, thousands lines of code. Also, modern C++ is much safer than unsafe rust. > C++ has no protection against the most pernicious memory management errors, particularl…

There is another kind of Rust graph that uses indices. Indices are just bounds checked addresses, so this is a natural fit. The most popular graph crate, petgraph, is of this type.

> CRT debug heap / MALLOC_CHECK_ / libefence, depending on the platform/compiler

None of these are effective at preventing use after free problems in production.

Post reply on HN