You're already using a language with a strong type system, so it's confusing to me why you would choose to draw the line here.
You're already using a language with a strong type system, so it's confusing to me why you would choose to draw the line here.
Yes because then I don't have to spend hours writing esoteric spaghetti code to prove something to the compiler that is trivially known to be true. Your error is assuming static lifetime checking is free. As an engineer, I use judgement to make context-dependent trade offs.
If you like playing the compiler olympics, or your employer forces you to, please use Rust.
Well said.
This is why i am firmly in the Stroustrup camp of backward compatibility/zero overhead/better-C/etc. goodness of "old C++". I need to extend/maintain/rewrite tons of them and that needs to be as painless as possible. The current standards trajectory needs to be maintained.
The OP article is a rather poor one with no insights but mere hoopla over nothing.
And that’s exactly the reason why we need more safety in C++.
I’m terrified at amount of code in real world written with this mindset.
I actually love the ideas that Rust brought forth. It definitely has a place in the ecosystem, and I'm glad to hear critical software is being rewritten in Rust! But that doesn't mean that C++ should copy it.
Is it fine if it silently gives the wrong answer? If so, why are you bothering with the software at all?
In my experience all nontrivial C++ codebases have silent memory corruption bugs (at least when built with popular compilers).
- Webkit, GCC, and a few others are non-trivial C++ codebases that are (I argue) useful.
- In your experience, since they are non-trivial, they have silent memory corruption bugs (i.e. they are not "perfectly safe").
Does this answer the "why bother with software at all" question?
Your examples of GCC and Webkit are both projects that have spent enormous amounts of effort to be as memory safe as they can be, and have both had many memory safety related CVEs in the past. As was already pointed out, you still have to pay the cost of engineering memory safe code, even when your compiler/static analysis doesn't have your back.
Not at our org. Though I know a couple of die hard fans that will eat you for lunch if you do something stupid or ugly.
The GCC/Webkit examples were not the best examples, but were nevertheless easily available examples that made one particular point: OP's comment was self-contradictory.
And I'd say that even with all that additional effort, it has a level of bugs that's not "fine". Indeed, per the article, I suspect that the maintainers of Webkit are some of the people pushing to make C++ more Rust-like.
Fundamentally I don't think this is a case where C++ makes a deliberate design tradeoff that makes sense for some projects. I think it's just a bad design choice (not even a choice as such - it wasn't a question that was considered at all when C++ was first designed) that should be corrected. Sometimes there is a right answer.
Indeed. And when that "right answer" comes along, it tends to swipe away everything else. If it's universally better, why wouldn't it?
Except that, Rust does not do that. Which is a hint that it's not an "universally right answer", but a right answer for a subdomain of problems. That's basically what I was trying to say. That it does come with its own tradeoffs/downsides.
(maybe I'm wrong and it's only a matter of time until that happens; but I don't think so.. it's been a while, there was time for it to make the impact. Lifetime annotations are not yet adopted by any other mainstream language, AFAIK)
> Except that, Rust does not do that. Which is a hint that it's not an "universally right answer", but a right answer for a subdomain of problems. That's basically what I was trying to say. That it does come with its own tradeoffs/downsides.
Rust may not be the only right answer, but memory unsafety is the wrong one. New projects overwhelmingly pick memory-safe languages, governments and organisations are banning memory-unsafe languages at least for new projects. I don't think anyone is picking C++ at this point if they don't already have a big sunk cost invested in it (even if that cost is just their personal programming experience).
> Lifetime annotations are not yet adopted by any other mainstream language, AFAIK
Linear Haskell is getting there, but most languages aren't flexible enough to retrofit lifetimes (or at best it would be a multi-year effort, like adding types to Python) - as we're seeing in this whole C++ discussion. Also non-GC languages are niche in the first place, and the problem lifetimes solve is a lot less urgent in a GC language. I don't think any post-Rust language has hit "mainstream" yet (we only really get a couple of new mainstream languages a decade), so we'll see what happens in the future.
If you think we should instead evolve C++ so that safety isn't mandatory I'm right there with you, but it's not where the language is today and that discussion has also been shut down by the evolution working group. Moreover, Bjarne's policies mean that telling the critical software people to go fuck off to a different language fundamentally isn't part of the plan either.
That is already a desirable place to be, where you managed to get a working implementation ready to evolve. My issue with opinionated languages like Rust is that they make development more expensive. I then afford to pay the necessary work-effort for fewer projects than I otherwise could if I was to focus more on the problem(s) at hand instead of that and other mandatory constraints forced upon me by the compiler. I very much want my development tools to limit themselves on being tools, to assist me on the part of the problem I chose to focus on with little to no cost paid for their usage. I want to be able to focus on prototyping some working solution first, and only then, if the project's needs really warrant it, to switch on paying the development cost for other aspects, be it safety or whatnot.
I don't think you've ever done any serious work with lifetimes. I've been a rust developer for a number of years, and I have never once encountered a situation where the rust compiler forces me to add annotations for something which is trivially true. Never.
What actually happens is 95% of the time I never have to add lifetime annotations anyway because the compiler infers the correct annotation from the lifetime elision rules. The remaining 1 in 20 instances is when the borrow checker yells at me, and literally every single time it is due to a latent logic bug in my code. For example, accessing memory after it's been freed, or using a container after it has been consumed. Stuff that C++ would call "undefined behavior" and are generally considered Very Bad Things by C++ developers as well.
It boggles my mind that you don't want the compiler to tell you that “you have a logic error here.”
The problem is that the rules enforced by Rust is not restricted to lifetime rules, it's a much much larger superset that includes quite a lot of safe, legitimate and valid code.
C++ isn't beholden to Rust's trade-offs either. There's a whole spectrum of possibilities that don't require broken backwards compatibility. Hence: "Why draw the line specifically at lifetime annotations?"
I'll have you know I made a variable void* just yesterday, to make my compiler shut up about the incorrect type :D