News for hackers. Stuff that matters.
Re:Rust – Compile Time Memory Safety by foota on Monday April 22, 2019 @09:56PM (#19724985)
Isn't the example with re-using a moved c++ vector completely safe?

    std::vector<int> x = {1, 2, 3};
    process(std::move(x));
    x.push_back(4);
    // Runtime invalid memory access
Re:Rust – Compile Time Memory Safety by kkimdev on Monday April 22, 2019 @10:01PM (#19724999)
Oh, I didn't know about this one. I did some search, and looks like it should be "valid but unspecified state" after move?

I can't think of any case that relying on unspecified state is desirable even if it's valid, though I guess it's better if I change that to x.pop_back(); to be clear.

Please let me know if my understanding is incorrect and thanks for the information!

Re:Rust – Compile Time Memory Safety by lmitchell on Monday April 22, 2019 @10:06PM (#19725013)
The only thing 'unspecified' guarantees you in this context is 'safe to destroy'. It specifically does not guarantee the safety of any other member functions - only the destructor. So either push_back() or pop_back() could potentially cause UB here (specifically, it's quite possible that the move swaps some internal pointers for nullptr, so you end up dereferencing null here - but morally, it's just never okay to continue using a moved-from object).
Re:Rust – Compile Time Memory Safety by millstone on Monday April 22, 2019 @10:22PM (#19725074)
The vector is "valid" and that is what carries all the weight here. The vector is still a vector.

push_back is absolutely defined. pop_back might be undefined, because pop_back is UB on an empty vector. If you like, call clear, and be assured of an empty, reusable vector. It's not idiomatic, but it's safe.

Re:Rust – Compile Time Memory Safety by pbsd on Tuesday April 23, 2019 @04:35AM (#19726608)
A moved-from std::vector<int> will always be empty. However, a moved-from std::vector<int, custom_stateful_allocator> may not be.

Howard Hinnant had a Stack Overflow reply a while back going through the possible corner cases of this precise question: https://stackoverflow.com/a/17735913

Re:Rust – Compile Time Memory Safety by marcianx on Monday April 22, 2019 @10:47PM (#19725174)
Yes, it's completely safe and its rust equivalent is

    let x = vec![1, 2, 3];
    process(std::mem::replace(&mut x, Vec::new()));
    x.push(4);
https://doc.rust-lang.org/std/mem/fn.replace.html
Re:Rust – Compile Time Memory Safety by khuey on Tuesday April 23, 2019 @01:01AM (#19725725)
There's no guarantee that std::move moves elements out of x. (and thus no guarantee that it's equivalent to a Rust mem::replace with a new Vec) The only requirement the C++ standard imposes is that the vector is left in a "valid but unspecified state".
Re:Rust – Compile Time Memory Safety by bluejekyll on Monday April 22, 2019 @10:09PM (#19725033)
It’s runtime safe (I’m taking your word for it). In Rust this would be a compile time error.

Although, are any C++ compilers able to at least issue a warning in this case? It wouldn’t surprise me if they could.

Re:Rust – Compile Time Memory Safety by zelly on Tuesday April 23, 2019 @08:50AM (#19728043)
Move constructors are allowed to call the moved object's destructor.

Not necessarily like the example given, but

  Object a {std::move(x)};
  x.push_back(4);
could/should segfault.
Re:Rust – Compile Time Memory Safety by ncmncm on Tuesday April 23, 2019 @10:21AM (#19728854)
No, move constructors are never allowed to call the moved-from argument's destructor. Ever.

Sometimes the compiler calls that destructor after it has finished the move, if the thing is no longer in scope. That should not be confused with a thing happening in the constructor.

Re:Rust – Compile Time Memory Safety by millstone on Monday April 22, 2019 @09:59PM (#19724993)
Yes it is safe.