Catch up on stories from the past week (and beyond) at the Slashdot story archive

 



Forgot your password?
typodupeerror
×
Programming

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.
This discussion has been archived. No new comments can be posted.

Rust Safety Is Not Superior To C++, Bjarne Stroustrup Says

Comments Filter:
  • by RoccamOccam ( 953524 ) on Saturday January 21, 2023 @04:50PM (#63228368)
    Borrowing Trouble: The Difficulties Of A C++ Borrow-Checker [google.com]

    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.

    • by Anonymous Coward on Saturday January 21, 2023 @05:01PM (#63228390)

      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.

      • 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.

        • by LindleyF ( 9395567 ) on Saturday January 21, 2023 @09:59PM (#63228896)
          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.
          • by petermgreen ( 876956 ) <plugwash@p10linI ... inus threevowels> on Saturday January 21, 2023 @10:55PM (#63228996) Homepage

            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.

            • by LindleyF ( 9395567 ) on Saturday January 21, 2023 @11:49PM (#63229098)
              So I've been reading about this borrow checker thing. The idea seems to be to force you to explicitly choose between passing by copy, move, and reference. That's something any decent C++ programmer should be thinking about anyway, but it's possible to make mistakes, so I buy that as a value proposition. There's also something about forcing mutable references to be singular; I can buy that as a boon to thread safety. It's a nice idea, to be sure. So the question becomes: is it enough to warrant a complete rewrite of a fully functional code base, or can C++ (with unit tests, sanitizers, lints, etc) get you enough of the same safety and better interop with existing code?
        • by lsllll ( 830002 )
          Hell! Rust allows you do to unsafe things as well. You just have to tell it to fuck off and let you do what you want.
    • by Talchas ( 954795 )
      The most obvious direct comparison is how C++11's move semantics are just laughably awful - in C++ moved-from objects still have destructors run and can still be accessed freely. (Also the default is still implicit copy rather than move, but C++ was always going to be stuck with that because of backcompat)
      • 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.

        • 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

          • Oh my god. You really think memory is actually moved.

            Tell me, what do you think happens when you move an integer? What do you think happens when you move a struct of integers?
            • 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.

          • You might misunderstand the argument. It's not that C++ is always safer; that's clearly not true. It's that C++ is safe enough that the cost of rewriting in another language isn't (usually) worth it.
            • 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.

              • I doubt very much C++ is being "abandoned". Those companies may be allowing or maybe even embracing Rust for new code in some cases, but there's still a massive C++ code ase that must be maintained.
      • 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.

        • 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.

          • 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?

        • That's a good thing. In most cases of you expect to want a move-only type, you should wrap it it a unique_ptr and call it a day. BTW, there are contexts where move semantics kick in without std::move().
          • I know it's a good thing. That's why I said it in reply to what the other guy was saying, in continuation of another comment of mine. I'm not saying this in a vacuum with no context.
      • Move semantics are fine. They leave the object in a "valid but unspecified" state, which may be defined on a per-type basis----unique_ptr will be null, for example. So you can destruct it or assign to it. But don't. C++ let's you do stupid things, that doesn't mean you should.
      • >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

        • When you think of things on a byte for byte level, of course copies and moves are the same in some sense. But with any nontrivial data structure including strings, copies are always deep, while moves are usually shallow.
        • by petermgreen ( 876956 ) <plugwash@p10linI ... inus threevowels> on Saturday January 21, 2023 @11:20PM (#63229050) Homepage

          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.

      • by Joce640k ( 829181 ) on Saturday January 21, 2023 @11:01PM (#63229010) Homepage

        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)

        • 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

    • by The Evil Atheist ( 2484676 ) on Saturday January 21, 2023 @05:42PM (#63228452)
      You don't need to change the C++ model. You can write static analysis tools to do the same thing, which is exactly what he talks about even in the summary. You literally can write a borrow checker as a tool, rather than make it part of a compiler.

      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.
      • by Cyberax ( 705495 ) on Saturday January 21, 2023 @06:12PM (#63228486)

        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.

        • At which point you'll get Rust.

          With the added bonus of not having to rewrite billions of lines of existing code.

          • by Cyberax ( 705495 )
            Actually, you'll have to rewrite them anyway to support "mutable xor shared" safety. Or put the existing code into giant "unsafe {}" blocks and just trust it to do the right thing.
            • That's not "rewriting". Adding annotations, or replacement with special types is not rewriting.
              • 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.

                • 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

                  • by piojo ( 995934 )

                    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.)

                    • The point is it is not going to cause a major rewrite, let alone a complete re-architecture of code, as some morons are claiming.
                    • by piojo ( 995934 )

                      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]

                    • So? That's REWRITING in Rust.

                      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.
          • Comment removed based on user account deletion
        • 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.

          • 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?

    • 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.

  • by narcc ( 412956 ) on Saturday January 21, 2023 @04:52PM (#63228372) Journal

    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)

      by StormReaver ( 59959 )

      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.

      • 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.

      • Common LISP is a fun language if parts of it are ignored as well.
        • by cstacy ( 534252 )

          Common LISP is a fun language if parts of it are ignored as well.

          I'm going to (declare (ignore your-argument)).

      • Huh. Templates can be immensely powerful and useful and allow you do away with a whole lot of legacy preprocessor nonsense. But in a time-honored tradition of backward compatibility, you can still shoot yourself in both feet very easily.
    • That interview: so what? He's always been talking about the need to improve C++. That's why he's been in the committee pushing changes along this whole time.
    • by Tom ( 822 )

      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.

  • Huh? (Score:5, Insightful)

    by backslashdot ( 95548 ) on Saturday January 21, 2023 @05:02PM (#63228392)

    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)

      by ffkom ( 3519199 )
      Easy to tout a language like "Rust" that did not have to prove much yet - with regards to amount and variety of software actually deployed and in use - as "safer" than programming languages that have been around for decades, and provide compatibility with even older programming languages.

      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
    • 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

      • 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.

  • Bjarne has a vested interest in C++ obviously, so take this with a pound of salt.

    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
  • by fahrbot-bot ( 874524 ) on Saturday January 21, 2023 @05:17PM (#63228412)

    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"?

  • by DrXym ( 126579 ) on Saturday January 21, 2023 @05:21PM (#63228422)
    And quite obviously. The Rust compiler will refuse to compile code if a programmer tries to use an object after it has been invalidated and similar scenarios whereas a C++ won't care and couldn't even if it wanted to.
    • Re:Yes it is (Score:5, Interesting)

      by Tailhook ( 98486 ) on Saturday January 21, 2023 @05:27PM (#63228432)

      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.

    • There are compiler and tool options to prevent use-after-move and other such cases too. Rust is not special, and C++ is not incapable of that.
      • by DrXym ( 126579 )
        If C++ compilers could enforce lifetimes or the other things like Rust then NOTHING would compile. But they don't and they can't enforce those rules even they wanted since the information isn't available for who owns what. So it is a nonsense that C++ is as safe as Rust.

        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)

          by The Evil Atheist ( 2484676 ) on Saturday January 21, 2023 @06:00PM (#63228476)

          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.

          • 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?

            • slices

              C++20 has the range library. Far superior to slices.

              split_at_mut

              Not needed with ranges.

              • 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++?

                • Looking at his paper, it sounds like he is comfortable with annotations, because it enables tooling. Personally, I'm fine with annotations. C++ compile times, while having been massively improved with modules, has been too long for too long. I would now actually prefer analysis happens as a separate process in the background, instead of slowing down my builds when I'm trying to iterate some code locally. It would even make CI faster, because faster compiles means faster testing, and the analysis tools can r
            • AddressSanitzer is pretty good at detecting things like use-after-free. Think of it like Valgrind but fast.
          • by DrXym ( 126579 )
            Nonsense. No one is saying that if you program in an extremely specific way you can't be safe. The issue is that C++ code doesn't conform and never will. And as a consequence there is CVE after CVE due to things the language allowed to happen. If C++ were actually fit for purpose there would be no reason for Rust to exist, something which is clearly not supported by reality.
            • 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.

  • by locater16 ( 2326718 ) on Saturday January 21, 2023 @05:47PM (#63228456)
    "Why not just be better programmers lol" Gee, thanks for the stack overflow level response
    • Re: (Score:3, Informative)

      by Dutch Gun ( 899105 )

      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,

  • by Pinky's Brain ( 1158667 ) on Saturday January 21, 2023 @05:54PM (#63228468)

    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.

  • Decades (Score:4, Funny)

    by insurgioFather ( 6387656 ) on Saturday January 21, 2023 @06:04PM (#63228480)

    FTFA: "I have worked for decades to make it possible to write better, safer, and more efficient C++"

    Well there you go.

    • 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.

    • "Man with decades of bias built up disagrees with everyone else. News at 11"

  • Possible (Score:5, Insightful)

    by allquixotic ( 1659805 ) on Saturday January 21, 2023 @06:44PM (#63228558)

    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.

    • Conversely, is it possible to write code in Rust that compiles to machine code that executes as fast and efficiently as compiled C++? If so then that’s an advance, no question.
      • 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.

      • 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.

    • It's nice that Rust prevents you from doing bad things. Another way to avoid doing bad things is to have unit tests which run under a sanitizer. As far as libraries go, yes, some are poorly written. Don't use those. Plenty of good libraries out there. Does Rust have anywhere near that library base?
  • Phillip-Morris says that cigarettes are healthy.
  • From TFS:

    I have worked for decades to make it possible to write better, safer, and more efficient C++.

    Just because you've done something for a long time does not mean you are good at it.

  • by Kremmy ( 793693 ) on Saturday January 21, 2023 @07:07PM (#63228612)
    There's something that I find unsettling about the idea that we need to move resource management into the language rather than keep it controlled by the developer.
    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.
  • In the immortal words of Mandy Rice-Davis. What's the point of such an obviously interested party to say anything on this subject?
  • by jd ( 1658 ) <imipak AT yahoo DOT com> on Saturday January 21, 2023 @08:01PM (#63228722) Homepage Journal

    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.

  • by inglorion_on_the_net ( 1965514 ) on Saturday January 21, 2023 @08:41PM (#63228792) Homepage

    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.

    • I'd argue that there is no bug-free language. All you can do is narrow the guardrails in certain categories. Now, languages like Rust may give you a hand in certain areas. But you'll still need to write tests to prove the program does what you think it does. Those tests are also guardrails. So, the question becomes, do Rusts guardrails offer protection that you don't already get from unit tests run under a runtime sanitizer?
  • by Tom ( 822 ) on Saturday January 21, 2023 @09:45PM (#63228874) Homepage Journal

    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.

  • 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.

  • by taleman ( 147513 ) on Sunday January 22, 2023 @05:42AM (#63229532) Homepage
    Ada is supposed to be memory safe. It's just that nobody seem to be using it outside of aerospace industry.

"Remember, extremism in the nondefense of moderation is not a virtue." -- Peter Neumann, about usenet

Working...