• Zacryon@feddit.org
    link
    fedilink
    arrow-up
    1
    arrow-down
    1
    ·
    edit-2
    1 day ago

    I’m not just talking about performance costs. For example, compared to C++, Rust comes with reduced flexibility and increased complexity in certain cases.

    The borrow checker, for example, imposes strict ownership and lifetime rules, which can be difficult to work with, especially in complex data structures or when interfacing with existing systems. Sometimes, you have to significantly refactor your code just to satisfy these constraints, even when you know the code would be safe in practice. This can slow down development, require more boilerplate, and make certain patterns harder to express.

    C++ gives developers more freedom but expects them to take responsibility. That tradeoff isn’t just about raw performance; it’s also about how much control and convenience the developer has.

    • qqq@lemmy.world
      link
      fedilink
      arrow-up
      7
      ·
      edit-2
      24 hours ago

      You said performance, so I responded to that. You can dislike Rust, that’s fine, but a lot of the things you’re saying aren’t correct. C++ isn’t memory safe, the person responding before showed that pretty easily. Rust doesn’t perform slower than C++, I responded to that claim. Rust provides tools to be memory safe, but the existence of unsafe I’d argue makes it also not memory safe, but at least better than C/C++. It also has tons of undefined behavior, just like those two.

      As for the personal opinion; you don’t have to like Rust. I actually have a very different view of the borrow checker and I don’t think I’ve ever “fought” it in a time when I was also doing something inherently safe. Every time I’ve had an issue with satisfying the borrow checker, which is rare, it’s been because I was doing something unsafe or interacting with C code, which Rust would argue is also unsafe. In my experience, it really eases the burden of programming actually and it makes debugging easier. It also makes design easier. As an example, I’ve been working on a very large C project recently and I ran into a bug where I was getting the wrong data printed out when I checked a value. After looking into it for like 15 minutes, I finally figured out that I had accidentally passed a stack pointer to a function that I wrote expecting a heap pointer. When the function went out of scope the data was garbage, but there was no crash and no compiler error. The borrow checker would have helpfully stopped me in my tracks there and saved that 15 minutes of debugging. The fact that it’s hard to implement your own efficient linked list or vector type has never been a problem for me really, especially not in comparison to the gains of not always having to keep ownership and lifetimes of pointers in my own head or in documentation that may go stale. I can’t express enough how helpful that is to my programming experience. C puts the burden of pointer lifetimes and ownership entirely on the developer. C++ makes that a bit better with the smart pointers at least, but those have some rules that aren’t enforced by the compiler but instead by convention.

      Basically I find the phrase “fighting the borrow checker” to be shorthand for “I can’t write C or C++ in Rust and I want to”. They’re not the same language and the constructs are different

      • Zacryon@feddit.org
        link
        fedilink
        arrow-up
        1
        arrow-down
        1
        ·
        20 hours ago

        That was not the only aspect, but yes, I mentioned that.

        I don’t dislike Rust. I find it pretty cool. However, I disagree with the blanket statement “C++ isn’t memory safe”. C++ provides the tools for writing memory-safe code, but it does not enforce it by default. That’s a design choice: favoring flexibility over strict enforcement.

        Yes, you can make mistakes that lead to memory issues. But that’s not a problem with the language itself; it with how it’s used. Stupid example: if you write code, which divides by zero at some point and you don’t make sure to check that, this is not the language’s fault, but your own.

        Of course a language can accomodate for stuff like that and lift some of that burden from the user. Surely there are plenty of use cases and user groups for that. And that’s totally okay. Rust was designed with memory safety in mind to prevent common errors that occur to a lot of devs during the usage of C++, which is fair. But that doesn’t make C++ less memory safe. It is intentionally open and flexible on purpose. There are various programming patterns and even functionality within the STL that help to prevent memory issues.

        So in other words: C++ is a tool, just like Rust. If you don’t know how to use the tool, that’s not the tool’s fault.

        C++ makes that a bit better with the smart pointers at least, but those have some rules that aren’t enforced by the compiler but instead by convention.

        You can always implement your own smart pointers. Besides that: which conventions do you mean?

        Basically I find the phrase “fighting the borrow checker” to be shorthand for “I can’t write C or C++ in Rust and I want to”.

        Nah, although it has its persk, I just think that it also imposes a rigid framework that sometimes forces you into cumbersome workarounds. With C++, you retain full control over memory management and can choose the best tool for the job. You’re not boxed into a strict ownership model that may force refactoring or add extra layers of abstraction. Instead, you have a mature ecosystem with decades of evolution that lets you balance safety and control based on context. Sure, mistakes can happen, but with proper practices and modern C++ features you can achieve a level of safety that meets most needs without sacrificing the expressiveness and efficiency you might require in complex systems.

        • qqq@lemmy.world
          link
          fedilink
          arrow-up
          2
          ·
          edit-2
          18 hours ago

          I disagree with the blanket statement “C++ isn’t memory safe”. C++ provides the tools for writing memory-safe code, but it does not enforce it by default.

          This is such a weird take. C++ isn’t memory safe. The blanket statement is… true. You say as much in the second sentence.

          With C++, you retain full control over memory management and can choose the best tool for the job. You’re not boxed into a strict ownership model that may force refactoring or add extra layers of abstraction.

          You have full control in Rust too, at least to the same extent as C++. Rust isn’t memory safe either. Rust is just the opposite of C++ in the approach to safety: you opt in to being unsafe with the unsafe construct instead of being unsafe by default. They’re just different paradigms. I’d actually argue that you don’t have full control in either language unless you opt in to it, modern C++ tries very hard to abstract away memory management. You can write an entire program without a single new or malloc, which is pretty great.

          Sure, mistakes can happen, but with proper practices and modern C++ features you can achieve a level of safety that meets most needs without sacrificing the expressiveness and efficiency you might require in complex systems.

          This is just simply not true and is consistently proven incorrect every time an aspect of C++'s memory unsafety is exploited. I work in security and I still, in 2025, exploit memory corruption. The best developers money can buy still make mistakes with C and C++.

          Besides that: which conventions do you mean?

          The way you have to interact with smart pointers for example:

          #include <memory>
          
          int main(int argc, char** argv)
          {
              std::unique_ptr<int> a = std::make_unique<int>(1);
              std::unique_ptr<int> b(a.get());
          }
          

          Double free, but compiles without warning. It’s convention to not use unique_pointer’s constructor, not enforced.

          #include <iostream>
          #include <string>
          
          int main(int argc, char** argv)
          {
              const char* c;
              {
                  std::string a("HelloThisIsAHeapString");
                  c = a.c_str();
              }
              std::cout << c << std::endl;
          }
          

          Use after free. No compiler error or warning, it’s convention to not maintain references to C++ string data, not enforced.

          That’s all fine, whatever, but these are conventions. We’ve shot ourselves in the foot a million times and come up with our own guard rails, but the developer needs to know all of them to not make the mistake.

          • Zacryon@feddit.org
            link
            fedilink
            arrow-up
            1
            arrow-down
            1
            ·
            edit-2
            17 hours ago

            This is such a weird take. C++ isn’t memory safe. The blanket statement is… true. You say as much in the second sentence.

            I suppose we need to make definitions clearer. C++ is memory safe in the sense that you can write memory safe code. It doesn’t enforce memory safety though. But not doing that is not the language’s fault. If someone jumps with a bike from a flying airplane, it’s not the bike’s fault that they will not land safely. It’s the misuse of the bike.

            The best developers money can buy still make mistakes with C and C++.

            I’d argue those weren’t the best developers then. However, I don’t want to get ridiculous. I see that there are problems in the common use of C++. Although I can’t share that from my experience due to usually proper usage, thorough testing use of additional tools, there is surely a need for aiding C++ devs with writing safe code. I know of the corresponding security concerns as well as probably everyone else in the C++ community.

            There are proposals to improve on that. Some of those might already come with C++26. Stroustrup’s favourite are Profiles to provide and enforce further guarantees, while others propsed an extension like Safe C++. Whereever the future will take us with C++, I’m confident that this issue will be sufficiently solved one day.

            There was a time when C++ wasn’t even designed for multi-processor systems, lol. That was redesigned pretty late. Much has changed and it will continue to improve as C++ continues to mature.

            Edit: Just saw your convention examples after I’ve sent my reply. Idk why it wasn’t displayed before.

            Regarding the double free: It’s clear from the documentation that this returns a raw pointer.

            Regarding the use after free:
            I really don’t want to sound arrogant as this is a simple example of course, but that is such an obvious mistake and looks like a topic which is covered in C++ beginner classes. To me, this is almost on the same level as dividing by zero and wondering about resulting bugs.

            but the developer needs to know all of them to not make the mistake

            Yes. Not every language is as user-friendly as python. With more flexibility come more risks but also more rewards if you’ve mastered it. It depends on what you want to do and how much you’re willing to invest. I would at least expect a professional dev to rtfm. Which itself is apparently already a problem. But, in the end of the day we want to use tools, which are effective and easy to use. So sure, point taken. I refer to the section before my edit regarding developments upon improving such aspects in C++.

            • WhyJiffie@sh.itjust.works
              link
              fedilink
              English
              arrow-up
              1
              ·
              7 hours ago

              I suppose we need to make definitions clearer. C++ is memory safe in the sense that you can write memory safe code. It doesn’t enforce memory safety though. But not doing that is not the language’s fault. If someone jumps with a bike from a flying airplane, it’s not the bike’s fault that they will not land safely. It’s the misuse of the bike.

              saying that C++ is memory safe because it’s possible to use it in a memory safe manner is like saying jumping out of a plane with the bike is safe, because it’s possible to safely land (with a parachute and a lot of training).

              you always repeat that C++ is memory safe because its possible, and that “misuse” is “not its fault”.
              first, you are quite simply redefining what does memory safety mean. you basically say bombs are safe because they can be safely defused with the expertise.
              second, do you really need to misuse it to get unsafe code? it does not warn anywhere. not in the instructions, not in the compiler output.
              third, its no one’s “fault” that c++ is not memory safe. That’s not a fault of c++. like its not a fault of factories that you have to wear safery gear when working inside because otherwise you may get injured more severely. this is just a property of C++, not a judgement

              I’d argue those weren’t the best developers then.

              oh no, my suspension was correct, you are really thinking that you are the perfect coder who jever makes any mistakes. It does not make sense to argue with you

            • qqq@lemmy.world
              link
              fedilink
              arrow-up
              5
              ·
              edit-2
              16 hours ago

              I suppose we need to make definitions clearer.

              The definition of “a memory safe programming language” is not in debate at all in the programming community. I have no idea why you’re trying to change it.

              I’d argue those weren’t the best developers then

              This is incredibly arrogant, and, tbh, ignorant.

              You missed the point of the examples: those aren’t necessarily “easy mistakes” to make and of course a UAF is easy to spot in a 4 line program, the point is that there is no language construct in place to protect from these trivial memory safety issues. With respect to the “obviousness” of the std::string mistake, if you instead consider an opaque interface that requires a const char* as an input, you have no idea if it is going to try to reference of that pointer or not past the lifetime of the std::string. If you can’t see past the simplicity of an example to the bigger picture that’s not on me.