Hacker News new | ask | show | jobs
by seabird 961 days ago
Herb is infinitely more qualified to speak on the matter than I am, but I don't think I understand the point. We've had multiple decades to bring C++ under control for safe general purpose usage and it's still very loosey-goosey, to the point where people are rightly afraid to start work in it not because it's a bad or deficient language, but because keeping codebases sane is challenging and requires a lot of discipline even from experienced programmers with an eye for detail.

I think C and C++ are two of the most interesting languages out there. I think it's rarely worth bothering rewriting existing C/C++ software in something else for the sake of safety. I think there's an appreciable amount of applications where C/C++ are still justified. I don't think this will end up being much different than the last two decades worth of attempts to put some guardrails on them.

TS is relevant because JS has severe functionality deficiencies and you've historically had no other choices when writing for web browsers. C++'s deficiencies are less with the functionality of the language itself and more with properly and safely using it, and you're very rarely forced to use it.

3 comments

It's not at all hard to build a sane codebase in C++ if you are a group of experienced C++ devs with an eye for detail. Not saying mistakes never happen, but most of the time the tools available are sufficient to build correct code if you know how to use them right.

However, the problems abound when you have less experienced devs in a less structured environment and working with legacy C or C-style code, the latter often being the reason for why C++ was used in the first place. For this, something like cpp2 can be revolutionising as it makes it easier to write correct code and provides mechanisms to disable many of the unsafe patterns.

I think the reality is that companies like Microsoft, Google, Apple want to write C++ but safer. The reason you're seeing Herb and Google's Carbon on the "ok fine well make a new language which has C++ interop instead of fixing C++" is because the C++ standards have been resistant to evolving the language into something that those companies want, to the degree that they may end up adopting Rust despite the absurdly high migration costs just because C++ refused to evolve into something those companies could use safely (even with people from those companies on the committees advocating for it).
Carbon's initial announcement was vague about how safety would be achieved. The late 2023 talks are clear that (a) It will be bolted on afterwards rather than foundational, which should be a major red flag and (b) It will not include some key things which Rust makes safe because they can't see how to do that at all in their design.

Herb's Cpp2 announcement on the other hand was clear from the outset that Cpp2 is not safe. It's aimed to be fifty times safer but that seems untestable, maybe even meaningless.

The immediate trigger for Carbon was P2137. Basically P2137 says "C++ should prioritise performance over safety, safety over compatibility" and WG21 is like "No, absolutely not". That's a set piece, nobody was astonished this happened, but getting it down on paper avoids executive argument. Google could have spent six years convincing non-expert people that C++ really isn't going to deliver, or it could secure a piece of paper which says they don't even want to and eliminate that whole discussion.

Apple have pretty clearly settled on Swift. I'm not convinced they can write all their bare metal stuff in a Swift dialect, or that they'll be able to in time to not need anything else long term, but clearly the vast bulk of new work at Apple will trend to Swift. Apple are quite good at single minded and "Write all new code in Swift" is a single minded idea. I have no idea why anybody would buy from a company like that, but they're very popular so what do I know.

Microsoft are much less single-minded. I doubt they could settle on Swift (or Rust, or even say sticking with C++) as a company wide policy even if they wanted to. But equally they're not interested in finding themselves as "last man standing" for C++.

> It will not include some key things which Rust makes safe because they can't see how to do that at all in their design.

To be fair, Rust does have an unsafe superset and the interaction between "safe" Rust and unsafe code is quite non-trivial. It's not safe to call any part of safe Rust from an unsafe context unless the extra preconditions that safe Rust expects (as documented in the 'Rustonomicon') are proven to hold. This means that, e.g. much of the Rust stdlib and 'core' code might not be practically usable from unsafe code written in either Unsafe Rust or C/C++, whereas the idiomatic C++ counterpart might be. There is some effort underway to fix this where it matters, but these are not easy questions to address.

I don't really agree with how you represent the difficulties of unsafe Rust.

First off, unsafe Rust is not meant for writing application logic. It should be isolated within data structures, algorithms, or other abstractions exposing safe APIs.

Secondly, what you say about calling into safe Rust from unsafe contexts just doesn't sound correct. It seems like by "extra preconditions" you're talking about the requirements placed on references: that they must be initialized, non-null, and for &mut, unaliased. But these aren't requirements for calling into safe code, these are requirements for dereferencing raw pointers.

You might also be talking about the issues around moveability and Pin. But these are also not about calling into safe code, but about representing your type correctly (making certain actions only possible when pinned or whatever).

And then you talk about std and view not being practically usable from unsafe Rust, and this just doesn't align with my experience at all.

It's really not that hard to get unsafe code right (Miri is an awesome tool), and it's also not difficult to avoid unsafe code entirely if you're not comfortable with the requirements.

> these are requirements for dereferencing raw pointers.

You can use the unsafe read() and write() (and similar) functions to do things with raw pointers that would clearly involve dereferencing in C/C++ (including working with aliased pointers or 'pinned' data or writing to uninitialized memory), so I don't think this is correct from a C/C++ point of view. What Rust calls dereferencing is explicitly driven by the requirements placed on safe code; the two are effectively one and the same.

The reason Carbon exists is because Google has a huge C++ codebase that they're stuck with, and Rust doesn't have a good C++ interop story. They don't really want "safe C++"; they want Rust. But because they have to interop with their existing C++ they're having to make a language similar to Rust but follows the C++ model closer (e.g. having move constructors).
I don't think it's really any more difficult to build sane C++ codebases than any other language. The issue is not sanity; it's safety.

It's extraordinarily difficult to build a significant C++ codebase without segfaults and UB. You end up wasting a huge amount of time debugging that stuff.

Any time I've lost fighting Rust's borrow checker has easily been paid off by not having to debug segfaults.

Not my experience at all. I work on very large C++ code bases and haven’t had a bug in production for more than 5 years. The trick is solid tests and using tools like Valgrind/Helgrind to remove all memory issues.
It also depends on what kind of application you're developing and the resource usage patterns.
Not at all. Tests + Valgrind/Helgrind (and similar tools) can cope with pretty much anything.