Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

> How is Rust so much more secure and reliable than *modern* C++?

Rust catches things like use-after-free at compile time. *modern* C++ still lets things slip through e.g.

    #include <iostream>
    #include <string>
    #include <string_view>

    int main() {
      std::string s = "Hellooooooooooooooo ";
      std::string_view sv = s + "World\n";
      std::cout << sv;  // oops, use after free
      return 0;
    }


If by "slip through", you mean "warns you about by default", then yes it lets it slip through.

  clang++ -std=c++17 test.cc
  a.cc:7:29: warning: object backing the pointer will be 
  destroyed at the end of the full-expression [-Wdangling-gsl]
      std::string_view sv = s + "World\n";
                            ^~~~~~~~~~~~~

In any case, I think the philosophical differences between C++ and Rust are well understood, and the different views of the cost/benefits there are also well understood.

In practice, rust will take over when it convinces enough C++ developers that the tradeoff is worthwhile.

That rarely happens by CTO's, or anyone else, telling everyone they are doing it wrong, but instead by helping people see easier ways of doing things, and ways to get work done faster/etc.

Or, you know, waiting for everyone who does it the old way to die.


> If by "slip through", you mean "warns you about by default", then yes it lets it slip through.

My bad. I should have been more modern. Try this one:

    #include <iostream>
    #include <string>
    #include <string_view>

    int main() {
      std::string s = "Hellooooooooooooooo ";
      std::string_view sv {s + "World\n"};  // {now even more modern and warning free}
      std::cout << sv;  // oops, use after free
      return 0;
    }


In other words, not a problem.


Except for the use-after-free?


Look - can we just admit that most C++ apps don't have thousands of use-after-free errors?

Of those use-after-free bugs that exist, they are a large source/percentage of the exploitable security bugs in C++ apps for sure. But again, it's not like apps are usually just littered with use-after-free. Like you may find one in a several million line of code app. They are not that common of a mistake, and FWIW, 100% of them are catchable with things like MSAN.

So people make mistakes. C++ makes certain kinds of those mistakes easy. Rust makes them hard or impossible. I don't think you will find any disagreement about this.

Again - this sort of thing is not going to convince anyone to use rust that doesn't want to already, for lots of reasons, not the least of because they think they are unlikely to make mistakes that matter :)

All this sort of thing does it turn people off from considering it for real, when they should!

(and i say all of this as someone who is funding efforts to replace billions of lines of C++ - i have no love for C++ over rust or vice versa. I just think the current approach here seems very unlikely to result in increased adoption)


> Look - can we just admit that most C++ apps don't have thousands of use-after-free errors?

For sure! It's those one-every-million-lines-of-code ones that are the problem, and that slip through code review and rear their head only in production at odd hours of the day.

> this sort of thing is not going to convince anyone to use rust that doesn't want to already

My post was in reply to someone asking the question what does Rust give you over modern C++, and this was an example showing that modern C++ still has its holes.

I'm not a Rust absolutist, nor do I think everything should be written (or rewritten) in Rust, but the biggest thing going in its favour is that offloads the cognitive load of checking lifetimes and ownership to the compiler, and that turns whole classes of runtime bugs in to compile time bugs.


Because nobody does this. An sv is a temporary you pass down the call chain, where it is uniformly perfectly safe.

This is why I say it takes extra work to get things wrong. Every example purporting to show "unavoidable" memory faults is super contrived. You have to turn off compiler warnings to be able to miss it.


My second example (the one you replied to) doesn't require you to turn off compiler warnings.

It might seem contrived, and it is, but it's the essence of a bug that has happened in the real world, distilled to a 10 line example.

And yeah, "use things properly or they will blow up", but enough people don't do that (or mostly do but occasionally slip up) that it becomes a problem.


In a large codebase with many warnings (incl from dependencies which you might not have control over), the difference between a compiler warning and hard error is significant.


It is easily made a hard error using -Werror, or you can even just make this an error if you don't want all warnings to be errors:

  clang++ test.cc -std=c++17 -Werror=dangling-gsl. 
  test.cc:7:29: error: object backing the pointer will be 
  destroyed at the end of the full-expression [-Werror,- 
  Wdangling-gsl]
        std::string_view sv = s + "World\n";
                              ^~~~~~~~~~~~~
It is pretty standard in large codebases in any language to carefully choose sets of warnings and errors.

I do think Rust has lots to offer, but i think the eternal argument here about what the compiler lets you do vs not is not likely to be a winning one with the C++ developers you see who don't want to move over.


`-Wall -Werror -Wextra` is the first thing to add to any project's cpp flags. And then selectively -Wno-whatever the stuff you don't really care about or is too annoying to go fix if it's an existing codebase


[flagged]


For trivial examples like this, it's easy to spot.

For modifications on a large codebase months (or years) after the original code happened, it saves significant time and effort to have the compiler catch bugs like this at compile time.


I mean I get it. On the other hand you really should know the constructs you are using. std::string_view is essentially a reference to a char array and you are assigning a temporary object (r-value) to it. Standard C++ rules say that you can't expect the lifetime of that object hold past the expression.


Sure I get it too.

If you want to write safe c++ you have to understand memory and lifetimes and what the code is doing. Humans have been shown to be quite bad at doing this - even experienced programmers.

Rust offloads that work to the compiler.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: