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

It takes longer to learn how to use C++ to the same level of proficiency and correctness compared to Rust, in my experience. It's harder to write an incorrect program in Rust.


What are the main correctness risks in C++ if you just never use a raw pointer?


I write c++ every day. Theres no such thing as "just never use a raw pointer", as existing code will use pointers, libraries become pointers, and there's no "non-owning" equivalent of a unique pointer. Even if there was:

- lifetimes are hard. The core guidelines recommend using span and string view, but correct usage of those isnt straightforward:

    std::string_view make(const std::string& in)
    {
        return in;
    }
Is not safe, at all. Span is also super dangerous:

    std::vector<int> vec = {1, 2};
    std::span<int> sp = vec;
    vec.push-back(1); 
Lambda capture semantics are another area where you might end up surprised by the behaviour too, (and by surprised, I mean you'll have memory issues).

Then there's all the normal stuff that still exists like slicing, lack of bounds checking, resource leaks because of improper inheritance use, data races, use-after-free issues. Sure these can be caught by a sanitizer with enough effort, but they still exist.


I don't know about "main", but like, you don't need raw pointers to have UB. uniq_ptr is nullptr after you move it.

And even then, my understanding is that raw pointers are still intended to be used in Modern C++: they're there for when you don't want to transfer ownership.


One thing off the top of my head, from experience:

std::string s(s);

To be fair, compilers will warn you about this nowadays. But when I converted a C codebase to C++ 20 years ago they didn't.

IIRC, references can also refer to de-allocated memory. Also, if you don't pass-by-reference or pointer, you can literally "slice" the dynamic doohickies off your instance so your AlbinoCat behaves like a Cat because all that extra special stuff is gone as far as the function is concerned.

This is just off the top of my head after not working with C++ for 20 years. I'm sure with all the new features it's gained over the past 20 years theres whole new exciting ways to blow your leg off.


how do you observe data you don't own if you never use a raw pointer or reference?

if you use shared ptr for this:

1. shared ptrs aren't made for this use case, they're for shared ownership 2. why using C++ at all if it means reducing its performance to an (atomatocally) performance counted language? Rust allows for much more performance with its safe borrowed references.

That also not what the CPP core guidelines, that are supposed to define modern C++, prescribe: For general use, take T* or T& arguments rather than smart pointers[0]. This rule incurs the risk of use after free if the returned reference is kept for too long by the caller. The rules for reference validity are non trivial (eg you returned a reference to an item of a vector, if you push into your vector you might invalidate the reference), so this is a significant source of bugs even in modern C++.

if you don't use shared ptr or references/pointers for this i'm curious as to which mechanism you're using to observe non owning data

[0]: https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines...


Well...

   UNSAFE {   
      // TODO: Verify all the lines, all the time, are ok
      // Just like you do testing, documentation, security and all that
      // ok?
      #include <iostream>
      using namespace std;
      int main() {

         // YOUR CODE
      }   
   }


What are you saying?


Well if the questions is:

> What are the main correctness risks in C++ if you just never use a raw pointer?

All the code on C/C++ IS a correctness "risks". Only constant, manual inspection could(maybe) say otherwise.

What Rust gives is significant reduction of the risks.




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

Search: