News for hackers. Stuff that matters.
Re:Please restore our registers when you’re done with them by von_lohengramm on Tuesday November 22, 2022 @01:58PM (#33709596)
I'm sure some C++ lawyer can correct me, but isn't branching off of `m_ptr` (e.g. `CHECK()`ing the value) after `std::move(m_ptr)` technically Unspecified Behavior since `std::move(m_ptr)` leaves `m_ptr` as an Unspecified Value? It would be up to the compiler to define the behavior if they so pleased, but the C++ spec would not require such behavior to be defined at all.
Re:Please restore our registers when you’re done with them by s28l on Tuesday November 22, 2022 @02:25PM (#33710069)
There is a big difference between "undefined" and "unspecified" behavior. In this case, the behavior of `unique_ptr(unique_ptr&&)` is in fact specified. [0]

However, the bigger issue with that code is that it can easily stop working with a simple refactor. Consider:

    void foo(std::unique_ptr<int> ptr) {}
    void bar(std::unique_ptr<int>&& ptr) {}

    int main()
    {
        std::unique_ptr<int> p1{new int{1}};
        std::unique_ptr<int> p2{new int{2}};

        foo(std::move(p1));
        assert(p1 == nullptr);

        bar(std::move(p2));
        assert(p2 != nullptr);
     }
Neither of the above asserts will fire, but from the calling site, they look exactly the same. In my opinion, the more explicit option would be to do something like `bar(std::exchange(p2, nullptr))`

[0]: overload (5) https://en.cppreference.com/w/cpp/memory/unique_ptr/unique_p...

Re:Please restore our registers when you’re done with them by account42 on Wednesday November 23, 2022 @06:00AM (#33717668)
Right, but changes in some other code potentially silently breaking assumptions at the calling site is exactly why you would want an assert like this in the first place.
Re:Please restore our registers when you’re done with them by tux3 on Tuesday November 22, 2022 @02:12PM (#33709854)
Moves in C++ don't make the whole object invalid, it just leaves them in a valid but unspecified state, so that at least the destructor can still run.

This means calling operator bool on your unique_ptr ought to be fine, because the unique_ptr still has a valid state (you don't know what that state is, it's unspecified, but it's guaranteed to not be radioactive on mere contact. It has to be a valid unspecified state.)

Re:Please restore our registers when you’re done with them by account42 on Wednesday November 23, 2022 @06:02AM (#33717691)
Moves in C++ are a function call that can do whatever any other function call can. The type itself can have additional guarantees and the standard library types generally do. In the case of std::unique_ptr the guarantee is explicit that the moved-from unique_ptr is nulled.
Re:Please restore our registers when you’re done with them by twoodfin on Tuesday November 22, 2022 @02:16PM (#33709909)
It’s an unspecified but required to be valid value for the moved type. The author mentions it’s a smart pointer type, which could easily be defined to act like this.
Re:Please restore our registers when you’re done with them by CamperBob2 on Tuesday November 22, 2022 @03:34PM (#33711101)
It appears that you need to be really smart in order to not blow your own foot off with this "smart pointer." I'll stick to the regular dumb kind, thanks.
Re:Please restore our registers when you’re done with them by CamperBob2 on Wednesday November 23, 2022 @01:37PM (#33722926)
Seriously, before downvoting, read the thread. When you find yourselves arguing endlessly about the distinction between unintended behavior, undefined behavior, and incorrect behavior in something as fundamental as a pointer, something has gone very wrong at a much earlier stage of the conversation.
Re:Please restore our registers when you’re done with them by brucedawson on Tuesday November 22, 2022 @07:41PM (#33713593)
I was wondering if anybody was going to point that out. It did occur to me that the CHECK was not technically valid due to that exact concern, but given that we control the compiler and the C++ library implementation and given that it's just debugging code (albeit debugging code that we ship to users) I'm fine with it.

In other words, I guess you shouldn't oughta do that generally, but I was fine with it being used there, and it did its job.

Re:Please restore our registers when you’re done with them by brucedawson on Tuesday November 22, 2022 @11:31PM (#33715189)
It appears that the question of what is valid on a moved-from object is tricky. Here is one discussion: https://stackoverflow.com/questions/7027523/what-can-i-do-wi... FWIW, here is the move operator for the type of the object in question: https://source.chromium.org/chromium/chromium/src/+/main:bas...
Re:Please restore our registers when you’re done with them by account42 on Wednesday November 23, 2022 @06:11AM (#33717755)
Note that the linked discussion is about the standard library. For your own types you can make whatever guarantees you want - ultimately as far as the language is concerned, moves are a function call like any other.