Rust Safety Is Not Superior To C++, Bjarne Stroustrup Says (open-std.org) 220
guest reader writes: The Open Standards site contains a new paper from Bjarne Stroustrup titled A call to action: Think seriously about "safety"; then do something sensible about it.
Bjarne reacts to an NSA report about Software Memory Safety since the report excludes C and C++ as unsafe. Bjarne does not consider any of the report's choices for "safe" languages as superior to C++ for the range of uses he cares about.
From Bjarne's response: I have worked for decades to make it possible to write better, safer, and more efficient C++. In particular, the work on the C++ Core Guidelines specifically aims at delivering statically guaranteed type-safe and resource-safe C++ for people who need that without disrupting code bases that can manage without such strong guarantees or introducing additional tool chains. For example, the Microsoft Visual Studio analyzer and its memory-safety profile deliver much of the CG support today and any good static analyzer (e.g., Clang tidy, that has some CG support) could be made to completely deliver those guarantees at a fraction of the cost of a change to a variety of novel "safe" languages.
Bjarne also complains that in the NSA's document, "'safe' is limited to memory safety, leaving out on the order of a dozen other ways that a language could (and will) be used to violate some form of safety and security." There is not just one definition of "safety", and we can achieve a variety of kinds of safety through a combination of programming styles, support libraries, and enforcement through static analysis.... I envision compiler options and code annotations for requesting rules to be enforced. The most obvious would be to request guaranteed full type-and-resource safety.
Bjarne notes that if you work in application domains which prioritize performance over type safety, you could "apply the safety guarantees only where required and use your favorite tuning techniques where needed." Partial adoption of some of the rules (e.g., rules for range checking and initialization) is likely to be important. Gradual adoption of safety rules and adoption of differing safety rules will be important. If for no other reason than the billions of lines of C++ code will not magically disappear, and even "safe" code (in any language) will have to call traditional C or C++ code or be called by traditional code that does not offer specific safety guarantees.
Ignoring the safety issues would hurt large sections of the C++ community and undermine much of the other work we are doing to improve C++.
The article also contains the following references for consideration:
- Design Alternatives for Type-and-Resource Safe C++.
- Type-and-resource safety in modern C++.
- A brief introduction to C++'s model for type- and resource-safety.
- C++ Core Guidelines, safety profiles.
Bjarne reacts to an NSA report about Software Memory Safety since the report excludes C and C++ as unsafe. Bjarne does not consider any of the report's choices for "safe" languages as superior to C++ for the range of uses he cares about.
From Bjarne's response: I have worked for decades to make it possible to write better, safer, and more efficient C++. In particular, the work on the C++ Core Guidelines specifically aims at delivering statically guaranteed type-safe and resource-safe C++ for people who need that without disrupting code bases that can manage without such strong guarantees or introducing additional tool chains. For example, the Microsoft Visual Studio analyzer and its memory-safety profile deliver much of the CG support today and any good static analyzer (e.g., Clang tidy, that has some CG support) could be made to completely deliver those guarantees at a fraction of the cost of a change to a variety of novel "safe" languages.
Bjarne also complains that in the NSA's document, "'safe' is limited to memory safety, leaving out on the order of a dozen other ways that a language could (and will) be used to violate some form of safety and security." There is not just one definition of "safety", and we can achieve a variety of kinds of safety through a combination of programming styles, support libraries, and enforcement through static analysis.... I envision compiler options and code annotations for requesting rules to be enforced. The most obvious would be to request guaranteed full type-and-resource safety.
Bjarne notes that if you work in application domains which prioritize performance over type safety, you could "apply the safety guarantees only where required and use your favorite tuning techniques where needed." Partial adoption of some of the rules (e.g., rules for range checking and initialization) is likely to be important. Gradual adoption of safety rules and adoption of differing safety rules will be important. If for no other reason than the billions of lines of C++ code will not magically disappear, and even "safe" code (in any language) will have to call traditional C or C++ code or be called by traditional code that does not offer specific safety guarantees.
Ignoring the safety issues would hurt large sections of the C++ community and undermine much of the other work we are doing to improve C++.
The article also contains the following references for consideration:
- Design Alternatives for Type-and-Resource Safe C++.
- Type-and-resource safety in modern C++.
- A brief introduction to C++'s model for type- and resource-safety.
- C++ Core Guidelines, safety profiles.
Google did a study about this (Score:5, Informative)
The conclusion: "We attempted to represent ownership and borrowing through the C++ type system, however the language does not lend itself to this. Thus memory safety in C++ would need to be achieved through runtime checks."
So, sure, if you are fine with slower code, C++ can be as safe as Rust.
Just that one aspect (Score:5, Insightful)
ITYM "if you are fine with slower code, C++ can be as safe in the same way as Rust."
The point is exactly that there's more to code safety than rusty pony's one trick.
While I think C++ is a huge language with possibly something elegant hidden within trying to get out, I also agree that just ignoring C and C++ beforehand as "not safe" makes the NSA study pretty much useless, if not outright propaganda. If they did do a thorough study with decent methodology they should have no problem showing their work. If you're doing a "language study" and start with ignoring the most widely used programming languages, then that smacks of cherry-picking.
So it's no more than proper that Stroustrup says that there's more to code safety than rust's borrow checker. That will remain true even should C++ fail on every possible other aspect for safety too. Which I'm sure it won't, as it isn't entirely a stupid language.
Re: Just that one aspect (Score:2)
Since C++ still allows everything that C has then it's still prone to many safety issues.
As I see it C++ has both the bad sides from C and object orienting with no benefits so I choose to avoid it except for special cases.
Re: Just that one aspect (Score:5, Insightful)
Re: Just that one aspect (Score:4, Interesting)
You are not obligated to use C++ as if it were C. That the language allows you to do unsafe things does not mean that you should.
The problem is even "modern C++" is still very much an "unsafe by default" programming environment.
1. you can use your fancy smart pointers to track memory ownership, but to actually do anything with the objects they point at you have to convert them, explicitly or implicitly (usually through the operator-> overload) to raw pointers or references. Once you do so there is nothing to gaurantee that the that the smart pointer is not modified during the lifetime of the raw pointer or reference.
2. With the standard collection types the pleasent to use access methods are the ones that do not have bounds checks.
3. There is nothing to prevent inadvertant passing of a non-threadsafe type across a thread boundary.
Re: Just that one aspect (Score:4, Interesting)
Re: (Score:3)
Re: (Score:2)
Re: (Score:2)
Also the default is still implicit copy rather than move
The default is to construct in-place wherever possible.
"Moves" are nothing special. They have, and will always be, byte-for-byte copies. Memory doesn't actually move. They're just bits.
Re: Google did a study about this (Score:3)
Hardly. Conceptually it might be a move in that once it is moved you can't do anything with it anymore within that scope, but this is almost always optimized into something much more simple at compile time. Indeed, even if *something* has to be moved, it's rarely the entire structure, and even more rarely (if ever?) requires a new allocation.
https://stackoverflow.com/a/30... [stackoverflow.com]
This likely isn't intuitive to you because achieving the same thing in C++ requires more work where, much the same as constants, it's j
Re: (Score:2)
Tell me, what do you think happens when you move an integer? What do you think happens when you move a struct of integers?
Re: Google did a study about this (Score:2)
Although you prefer to cp and then rm your files just to prove a point to yourself and teach the world whose boss, I'll simply use mv. Unlike you, I use the right tool for the job, much as I'll use the right terminology. You and your invisible man aren't as clever as you think.
Re: Google did a study about this (Score:3)
Re: Google did a study about this (Score:2)
For which? What Stroustrup said? He's arguing that Rust is doing harm to the C++ community because apparently Microsoft, and now Google, are abandoning C++ for all greenfield work in favor of rust. That isn't rust's fault. He designed C++ and for the most part calls the shots, so if that's really the case then ultimately he bears responsibility for its deficiencies, not rust.
Re: Google did a study about this (Score:2)
Re: Google did a study about this (Score:4, Interesting)
It would probably be better to make a C++ compiler with a switch to disallow allow the unsafe stuff.
That fundamentally won't work. Actually I read a quora post recently about this that is gold:
https://www.quora.com/Is-Rust-... [quora.com]
...Everything else is hard, even prohibitively, but theoretically negotiable, for a constrained subset of C++. You can even annotate library dependencies that don’t follow the constraints, and get a bit closer, which might allow for a codebase to be at least sanitized to the point of localizing sources of issues to external libraries. But there’s a deal breaker, a fundamental issue that means that, in C++, ownership can never be correctly checked at compile time, statically, that interfaces will always bleed.
In C++, moves are non-destructive. And changing this would have broken so much legacy that it was never really on the table. Even if - and I stress that this would have been grotesquely contrary to “don’t pay for what you don’t use”, and horrible for performance - but even if you moved to 100% heap-based allocation for objects passed between call points, you couldn’t guarantee lifetimes across moves.
And Rust, in solving this, in showing the slip to the Gordian knot, finally clarified the fundamental non-solvability of the problem in C++. Because you cannot create a subset that will allow exposing ownership through a library interface in a way that allows reasoning at compile time, both in the library and in the consuming application code. Not when call signatures can make no guarantees about ownership after the call completes.
Okay, yeah, theoretically, you could annotate every parameter passed in a form that could copy or move. You could require lint-binding contracts on everything. You could enforce runtime checking on all foreign interfaces. You could prohibit naked references. But the result would not be usable. Not really. And at the end of the day you would have a Rust clone with terrible ergonomics, missing features, a functionally broken subset of the borrow checker, no ecosystem, a syntax that was a constrained intersection with C++ (subset + technically valid comment annotation superset), foreign library compatibility not much better than bindgen-wrapped FFI in Rust, and zero adoption.
Because anyone who cared that much, and was willing to put up with that much, and learn that much new, would be better served by defining a clean interface and moving that part of their project to Rust.
Basically what you're asking for is Carbon, and Google didn't create Carbon for greenfield work. For that, they're using Rust. Carbon is meant as a happy medium for existing code, because ultimately it has all of the problems the quote above mentions.
Making a generation of people who are real C++ programmers instead of "C programmers using C++ compilers" would be a good thing.
C++ is itself a programming language of two generations ago. Sure, what came after was a range of garbage collected languages, but at least they...mostly...offered memory safety. Now we have languages like Rust and Swift where you can have memory safety without the garbage collector, in addition to doing away with numerous old mistakes like null pointers in favor of optional types, and forcing the programmer to at least acknowledge potential hard error conditions where previous languages wouldn't even hint to you that they had any kind of error condition at all.
In order to even give all of that to C++, you're not only talking about overhauling the language, but rewriting all of the major libraries as well. I guess you could do all of that if you want to if you're just hell bent on not letting C++ go the way of fortran. But you'd be doing that just because you just want the C++ branding, because what you'll end up with really wouldn't be C++ anymore. Indeed, at that point you've just rewritten Rust.
Re: (Score:2)
Also the default is still implicit copy
Furthermore, if you use uncopyable types, like unique_ptrs, files, etc, in an type, that type's copy-special-functions are disabled. It's not even moveable until you explicitly request it to be moved.
Re: (Score:2)
Also the default is still implicit copy
Furthermore, if you use uncopyable types, like unique_ptrs, files, etc, in an type, that type's copy-special-functions are disabled. It's not even moveable until you explicitly request it to be moved.
So it's not moveable with one line of code, but a different line of code can move it. Them it's just moveable and your language is imposing a constraint. The computer can copy and move things all day. Getting tied up in the type system of a language implies the language is getting in the way of doing what you want to do.
Re: (Score:2)
So it's not moveable with one line of code, but a different line of code can move it. Them it's just moveable and your language is imposing a constraint.
And Rust isn't a language that is imposing a constraint? Do you really believe Rust changes how a computer works?
Getting tied up in the type system of a language implies the language is getting in the way of doing what you want to do.
And Rust isn't about getting in your way to prevent errors?
Re: Google did a study about this (Score:2)
Re: (Score:2)
Re: Google did a study about this (Score:2)
Re: (Score:2)
>Also the default is still implicit copy rather than move
Everyone else is responding to this bit, so I will have a go too..
Implicit copy is the default because that is exactly what computer hardware does. When I move the value at address A to address B, the value is still at A. There is also swap, which does what the name suggests and is in hardware for obvious reasons. Anything else on top imposing other behaviours is an abstraction. Abstractions are fine if they fit your solution domain, but efficiency
Re: Google did a study about this (Score:2)
Re:Google did a study about this (Score:4, Interesting)
Implicit copy is the default because that is exactly what computer hardware does. When I move the value at address A to address B, the value is still at A.
Indeed, and that line of thinking works fine as long as your variables are agreegates of dumb values and unmanaged pointers. Indeed for "trivially copyable" types even rust is copy by default.
Once you introduced managed pointers though you have a problem. If you make a copy of a type containing managed pointers and then run the destructor on both copies then you have a double free bug. Similarly if you overwrite the contents of such a type without freeing the old content first you have a memory leak.
And it is for such "Managed" types that rust and C++ differ. In C++ a simple assignment can turn into a call to an arbitarily complex copy constructor. In the case of collection types containing a managed type that copy constructor will in turn call the copy constructors for all the types contained with in.
C++11 introduced the concept of "moves" but asside from not being the default, they are also required to leave the type in a "valid but otherwise unspecified" state. This means that each type needs it's own custom move constructor which practically means the types cannot be passed in registers but must be passed on the stack. It also practically means that your smart pointer types have to support a "null" state.
Rust take a different approach, the compiler keeps track of whether a given address contains a "valid" object or not. At an instruction level a move is just a copy but the key difference is that after the move the compiler no longer treats the source as containing a valid object. So drop (rust's equivilent of a destructor) will only be called once.
Re:Google did a study about this (Score:4, Insightful)
C++ moved-from objects still have destructors run and can still be accessed freely.
If that breaks anything then you're Doing It Wrong.
A moved-from object should set all its pointers to null, etc., so the destructor has no effect. It's the entire point of a move operation.
(Anything else is a "copy" operation)
Re: (Score:3)
C++ moved-from objects still have destructors run and can still be accessed freely.
If that breaks anything then you're Doing It Wrong.
A moved-from object should set all its pointers to null, etc., so the destructor has no effect. It's the entire point of a move operation.
(Anything else is a "copy" operation)
What you're saying (and what Bjarne is saying) is that with a lot of care and discipline, modern C++ can be as safe as Rust. I agree with that. But with a lot of care and discipline, you can write correct code in any language. Modern C++ helps you more than some, but not nearly as much as Rust.
FWIW I've been writing C++ code for more than 30 years, and until I encountered Rust it was far and away my favorite language. At this point I still like C++, but mostly because I'm sentimental about it. For code th
Re:Google did a study about this (Score:5, Interesting)
The Core Standard Guideline support library is one of those things that, coupled with the newer language capabilities, is being used to do stuff like this.
Re:Google did a study about this (Score:4, Insightful)
You can write static analysis tools to do the same thing, which is exactly what he talks about even in the summary.
Sure. You'll just need to annotate types with lifetimes in ambiguous cases. Then to guarantee safety you'll need to add borrowing and exclusive ownership.
At which point you'll get Rust.
Re: (Score:3)
At which point you'll get Rust.
With the added bonus of not having to rewrite billions of lines of existing code.
Re: (Score:2)
Re: (Score:2)
Re: Google did a study about this (Score:2)
You honestly believe that existing C++ code out in the wild today would most likely pass a borrow checker with just some extra ownership info tacked on?
Nope. Nope. LOL! Nope.
If you can get away with just a major refactor, you'd be lucky. All other cases, the entire architecture would likely need to be vetted, resulting effectively in a rewrite. The only things preserved would be auxiliary modules and perhaps the project name.
Re: (Score:3)
You honestly believe that existing C++ code out in the wild today would most likely pass a borrow checker with just some extra ownership info tacked on?
No, there will always be errors. But the "fixes" won't be much. The "fixes" would mostly just be to change the types of some variables here and there.
If you can get away with just a major refactor, you'd be lucky.
C++'s whole schtick is backwards compatibility. You must be thinking of irresponsible language designers who have no problem breaking your code for the next fad.
the entire architecture would likely need to be vetted, resulting effectively in a rewrite.
Which is nonsense. You do know that most bugs are fixed without rewrites, right? That's what these checkers would do - find bugs for you to fix. Making the code compliant with a checker is just bug fix
Re: (Score:2)
You honestly believe that existing C++ code out in the wild today would most likely pass a borrow checker with just some extra ownership info tacked on?
No, there will always be errors. But the "fixes" won't be much. The "fixes" would mostly just be to change the types of some variables here and there.
Haha, I don't think anyone that's ever actually written Rust would say that. Everybody has experienced something like a simple loop that modifies a variable, and is obviously safe but won't pass the borrow checker. (Though in some cases the borrow checker is obviously too strict and a better borrow checker would allow simpler code. But I wouldn't glibly claim annotations are sufficient until such an "easy borrow checker" exists.)
Re: (Score:2)
Re: (Score:3)
Hmm, I think it will if the architecture involves shared access to central objects which are sometimes needed to be mutable. The Google Security Blog explains why Chrome couldn't be written in Rust without a major change in architecture:
https://security.googleblog.co... [googleblog.com]
Re: (Score:3)
There was no massive change when we went from C++98 to C++11 with unique_ptr and shared_ptr. There was no massive change to push for std::vector where possible. There was no massive change when threading was introduced. There was no massive change when move semantics was introduced. There was no massive change when the rules were expanded to allow copy-elision and move-elision in tons of places.
All of those improvements to lifetime management happened without major change.
Re: (Score:3)
I guarantee you they've already tried.
I guarantee you they haven't. Just even look at Google's coding guidelines for C++. Complete rubbish.
It's sweet you think that just because someone works at Google that they are competent.
Re: Google did a study about this (Score:2)
They're a lot more competent than you. Though admittedly that doesn't say much.
Re: Google did a study about this (Score:2)
Re: (Score:2)
Re: Google did a study about this (Score:2)
Most Rust code just uses reference-counting, because the whole model is too constraining to model things in smarter ways.
While I would argue this is proof that Rust has failed to deliver on its original premise, people seem to love many things about Rust beyond its borrow checker.
Re: Google did a study about this (Score:2)
No, it doesn't, you're thinking of Swift. Reference counting in rust is never implicit. Ever. If you want it, you have to explicitly encapsulate your data into Arc or Rc. If reference counting was implicit, then why the fuck would you even need a borrow checker?
Re: (Score:2)
So, sure, if you are fine with slower code, C++ can be as safe as Rust.
The point is that in C++ you get to choose when/where the code slows down.
And if we're honest: If you're still "overflowing a memory buffer" in C++ then you're Doing It Wrong.
Very wrong.
C++ is a cruel joke. (Score:5, Funny)
Does anyone remember this? [duke.edu]
I don't know if Rust is the way forward, but I do know that we need to leave C++ in the dustbin of history.
Re: (Score:3, Interesting)
I set out to learn as much C++ as possible, including a large chunk of the standard template library. I didn't get very far into template programming before realizing that C++ templates were complete and utter garbage for most purposes. I took a step back to using C++ as C with classes and objects, and life improved dramatically.
C++ has added some really useful stuff, such as official support for threading, but I avoid all the parts of it that use, or even resemble, templates in order to preserve my sanity.
Re: (Score:2)
C++ templates were complete and utter garbage for most purposes.
Most purposes would be for simple genericity at compile-time. Sounds like you were trying to do the metaprogramming stuff, which was meant to be left for library writers.
That being said, the templates stuff are all compile-time checked. You are avoiding a whole class of safety AND performance improvements by not using templates.
Re: (Score:2)
Re: (Score:2)
Common LISP is a fun language if parts of it are ignored as well.
I'm going to (declare (ignore your-argument)).
Re: (Score:2)
Re: (Score:2)
Re: (Score:2)
Someone at Mickeysoft had the same sense of humor and built C#
Want to write really fragile code that explodes in unexpected ways? There you go.
Re: C++ is a cruel joke. (Score:4, Interesting)
Buffer overflow is still possible in Rust. Code that is exploitable is also still possible. Itâ(TM)s easy to say you can write safe code if you never need to do anything complicated like interface with memory or hardware.
Re: C++ is a cruel joke. (Score:2)
You have to deliberately go way out of your way to do that with something like Vec::get_unchecked, which is marked as unsafe and so you'd have to encapsulate it into an unsafe scope. Unlike with C++, unchecked bounds are never accidental in rust. More than that, nobody ever bothers with anything like that in all but the rarest cases because A) the compiler typically optimizes the bounds check out entirely and B) even if the bounds check is needed, the cost is extremely negligible, assuming it even makes any
Re: (Score:3)
Unlike with C++, unchecked bounds are never accidental in rust.
My C++ has full range checking turned on by default for all std containers.
Huh? (Score:5, Insightful)
He is saying it is safer if you use it properly according to the guidelines. Well, no shit .. that is every language. The point of Rust is that you would have to deliberately be an ass to make it unsafe, not just be careless.
Re: (Score:3, Insightful)
Yet we have seen entirely "memory safe" and "sandboxed" languages like JavaScript involved in thousands of security leaks, proving that "safety" is not so much a programming language than a programmer competence feature.
J
Re: (Score:3)
C++ is a bit different than most languages in that it includes most of the C language, along with all it's well-known language and library safety issues. You can write C code and technically call it C++, but it's a very far cry from the safety provided by writing in modern C++, with a combination of RAII and smart pointers, which by themselves offer very strong safety guarantees enforced by the compiler. The difference is that in C++, you don't have to explicitly call out unsafe code via a keyword, and so
Wonder if you could flag it all (Score:2)
So, in C++, you essentially have to opt-in to safety by deliberately avoiding the built-in C language AND older C++ techniques
It's been a while since I used C++, but I have to think some compilers offer flags you could enable that would disallow any older, unsafe techniques and thus would give anyone working on that project the sam guarantees about memory safety at least that Rust offers...
Again not sure if that is the case, just knowing how many compiler flags most compilers have it seems likely.
Blernch. (Score:2)
I use both languages. They both have serious issues. C++ is a homemade bomb as far as safety and I'd think that by now after all these decades, people would have realized that you can't really write fully safe C++.
Rust is a pile of unicorn queefs at the moment with core parts of the language undocumented, and compiler magic abundant. Standardization seems like a pipe dream because parts of the language grammar will need t
the range of uses he cares about (Score:4, Insightful)
Bjarne does not consider any of the report's choices for "safe" languages as superior to C++ for the range of uses he cares about.
That doesn't really help, except for cherry-picking things.
What if one wants undetectable errant memory conditions?
Can a language that helps facilitate, or doesn't hinder, that then be called "safe"?
Yes it is (Score:3)
Re:Yes it is (Score:5, Interesting)
Mozilla and others have clear data on memory safety defects in Rust components. The results are clear; work-a-day code written in Rust is demonstrably safer than work-a-day C++. The debate is over, except in the minds of the malcontent. Sadly, it appears Stroustrup must be counted among them.
Re: (Score:3)
Meanwhile, Google announced this month that the Chrome browser would start incorporating Rust into its codebase.
Re: (Score:2)
Re: (Score:2)
Aside from that, Rust wouldn't even be a thing if C++ were actually safe, which clearly it isn't.
Re:Yes it is (Score:4, Informative)
If C++ compilers could enforce lifetimes
C++ compilers already enforce lifetimes. It's called RAII. The exact same thing that Rust uses.
since the information isn't available for who owns what
Yes it is available, and information can be added. C++23 will be released this year. The Core Standard Guidelines has been continually evolving alongside, with stuff that is used to add more information.
It seems you are completely in the dark about C++ since C++98.
Re: Yes it is (Score:3)
So where can I find the equivalent annotation for say slices and split_at_mut? Is someone actually standing up and producing an annotation standard, verification tools and an entirely new standard library and STL which uses them?
Re: (Score:3)
slices
C++20 has the range library. Far superior to slices.
split_at_mut
Not needed with ranges.
Re: Yes it is (Score:2)
I must admit, stuff is happening, but a lot of it seems to be happening in clang instead of the core guidelines.
Is Stroustrop actually comfortable with lifetime annotation or does to him everything have to be inferred from his standard C++?
Re: (Score:2)
Re: Yes it is (Score:2)
Re: (Score:2)
Re: (Score:2)
The issue is that C++ code doesn't conform and never will.
Conform to what?
And as a consequence there is CVE after CVE due to things the language allowed to happen.
The CVEs are mostly for C. People won't stop writing C. Stop writing C if there's a C++ replacement.
Re: (Score:3)
Ah yes, C++'s legendary lifetime tracking
#include <iostream>
using namespace std;
const string &hello() { return "hello"; }
int main() {
cout << hello();
return 0;
}
If you're lucky, you might get a warning from the compiler before it happily compiles this broken code.
Old Man Says youngins suck (Score:4, Funny)
Re: (Score:3, Informative)
It kind of sounds like a "git gud" argument, but it's really not the same as I see made by some C programmers.
The difference is this: with C++, if you follow some reasonably straightforward design principles when writing software, you can ensure the compiler will mostly prevent you from making mistakes. The trick is to know how make use of RAII to write small, self-contained components that are memory-safe themselves, and build your programs from those types of components. This is a bit different from C,
Why guidelines? (Score:3)
Why not a pragma for safe C++ which allows some C++ keywords to take on entirely new meaning?
The dogma that a safe version can just be implemented on top of backward compatible C++ seems to not have convinced either Mozilla or Google.
Re: (Score:2)
Won't they ?
Re: (Score:2)
Decades (Score:4, Funny)
FTFA: "I have worked for decades to make it possible to write better, safer, and more efficient C++"
Well there you go.
-Werror (Score:2)
With every new release of LLVM or gcc there will be new compiler warnings flagging one's code as problematic.
But this assumes buy-in from management to refactor a code base by littering C++ code with 'safe' annotations mentioned in the linked papers?
c.f. Torvalds only enforced "-Werror" in 2021, with 3 decades of warning-laden contributions to the Linux kernel.
News at 11 (Score:2)
"Man with decades of bias built up disagrees with everyone else. News at 11"
Possible (Score:5, Insightful)
His own words admit the faults:
"I have worked for decades to make it possible to write better, safer, and more efficient C++"
POSSIBLE. It's also possible to write safe Intel x86_64 machine code, but who has time to learn how to do that except for someone trying to optimize the hell out of a hot inner loop in the OS's scheduler or something?
On the flip side, it's possible to write Rust code that produces a segfault, but you have to use a keyword that says "unsafe". Pointer deferences in C++ that crash your program can be done without even a compiler warning or a hint that what you're doing may be incorrect.
And there's so much legacy code in C++ out there that any real program is going to end up using libraries with badly designed APIs that have "gotchas", undefined behavior, or call interleaving patterns that cause memory or thread safety problems.
If your whole stack is written in Rust, none of what I said is possible, assuming people don't just use the "unsafe" keyword for laughs, and seriously consider and test each location where it is used.
Re: (Score:2)
Re: (Score:2)
Aside from a very few special cases, it is clear that speed and efficiency are not a goal of nearly all programming being done in the world. Convenience won.
Now if you'll excuse me I have program to write. ... I mean I say program, what I mean is a poorly functioning barely working piece of javascript packaged in a way that encapsulates a complete instance of a Chrome browser every time you execute it. You know, "modern" programming.
Re: (Score:2)
One of the goals of Rust was implementing zero cost abstractions in a high-level language, no?
Clang and Rust both target the same intermediate representation (IR) layer - in theory they could generate identical machine code depending on the optimizations in LLVM.
Re: Possible (Score:2)
In Other News (Score:2)
Long time (Score:2)
Just because you've done something for a long time does not mean you are good at it.
I don't believe these features help the programmer (Score:3)
A lot of these ideas seem to be focused on eliminating the sort of manual memory management that C and C++ allow, which prevents developers from learning how to manage computer resources effectively. They don't understand what to do when something breaks at a level where the language is not holding their hand.
Look at how C pointers are treated as an arcane, difficult mechanism. It's a memory address, that's all it is, but look at how hard that concept apparently is.
It feels like expecting the car to steer for you while pretending that the steering wheel is an arcane mechanism that you can't figure out by looking at it.
He would, wouldn't he? (Score:2)
Ish. (Score:3)
Ok, you can definitely use Z3, HOL, or Isabelle to prove C programs correct (SEL4 does this), and the VST project is a toolchain that compiles a subset of C into binary that provably matches the source.
You can also use Coloured Petri Net software to generate C code from a CPN model, although I'm not willing to vouch on code quality.
You can model-check C++ programs (https://arxiv.org/abs/2107.01093) and conduct other formal proofs for a subset of C++.
It surprised me to learn that Rust is not idle in this field. I'd expected the language to be too new or too complex for provers. But I was wrong. Here's a list: https://github.com/newca12/awe... [github.com]
So if we're going by absolute top-end zero defects, C, C++ and Rust are roughly equivalent.
If we're talking mid-range "I don't have three years to wait for the proofs that software engineers can perform TDD from, but I need adequate trust that the code behaves", then Rust is the clear winner.
So it really depends on what level you're talking about as to whether Rust is better or if C/C++ are comparable to Rust in terms of quality.
I Read Some of What He Suggests (Score:5, Insightful)
I went and read some of what Bjarne wrote, because I was curious. My verdict? A lot of words that don't add up to a solution.
The main theme can be summed up as "C++ is unfairly characterized as memory-unsafe, and besides, there are other safety properties we should care about."
He is, of course, right about the last part. But that doesn't negate the fact that lack of memory safety continues to be a huge source of real problems in real software.
As for the first part, I took a look at some of the work he references that he claims make C++ actually memory-safe. In short summary, the idea is a set of rules, mentioned in Type-and-resource safety in modern C++ [open-std.org]:
1. every object is accessed according to the type with which it was defined
2. every object is properly constructed and destroyed
3. every pointer either points to a valid object or is the nullptr
4. every reference through a pointer is not through the nullptr
5. every access through a subscripted pointer is in-range
Then there are a host of programming rules (e.g. "don't use casts") and proposed static and run-type checks that, when implemented and used, would help enforce those rules.
Some static checks are claimed to exist, others remain to be implemented. Some checks, Bjarne claims, will have to be made at run-time (such as checking that a pointer being dereferenced is not nullptr). And a lot is left to "style rules".
Don't get me wrong, a lot of the recommendations Bjarne makes are good. But I was hoping it would add up to being able to statically verify the memory safety of C++ to the same level you can with Rust, and it does not. It's more like "If you follow these rules that preclude much of the language[1], it can be safe, although we can't prove it at compile time." [1] Convincing everyone in your organization that this is a good idea, and then rigorously enforcing it without any mistakes is left as an exercise to the reader.
Oh, and "Not everyone prioritizes 'safety' above all else.".
Which is, of course, why the NSA made its recommendation. We have had memory-safe programming languages for longer than we've had C++, but we continue to "prioritize" in a way that allows attackers to take over our computers, extract our data, etc. After decades of this, the NSA has said "Enough of this, we're going to put out an official recommendation and call out some problematic and better languages by name". Bjarne is saying "Now, now, let's not be hasty, C++ is perfectly safe if you carefully avoid all the pitfalls." Which we have tried to do for the last 20 years or so, and it has not been working. This recommendation isn't being hasty; if anything, it's quite long overdue.
Re: I Read Some of What He Suggests (Score:2)
"Inventory of language claims language is good" (Score:3)
News at 11.
Can you write safe code in C++? Sure you can. You can also write it in C or ASM. Or any other language. The question isn't if an expert can do it, but how wall beginners (in that language) can avoid writing unsafe code.
The Rust ownership model is infuriating at times, but it pretty much prevents a whole class of mistakes. That makes sure that even beginners can't make them.
Re: (Score:2)
This Guy Is An Idiot (Score:2)
C++ is a garbage language and needs to be left behind like so many others. Powerful, sure, but, just like C and Objective-C, it's writability and readability is low. It has tons of nuances where it *seems* like this code should work (and the compiler oks it), but in reality, you need to do it this completely other way. C# is the only "C" language that has any merit to it, currently. C++ is just a stepping stone along the way, stop trying to prolong its stupid life.
What about Ada? (Score:3)