Date: Thu, 24 Apr 2025 21:27:06 +0300
On 24 Apr 2025 19:45, Jonathan Wakely wrote:
>
> In a language where the compiler does not (and in general can not)
> prevent you from using a moved-from object, it isn't a good idea to
> make moved-from objects radioactive and unsafe. The reason Jon's
> argument doesn't make sense for me is because ... this is C++. We
> don't have a lifetime-checker or borrow-checker that would allow his
> desired model to work.
>
> Frankly, I struggled to find any part of the talk I agreed with.
>
> The ViewPort example is just dumb, nothing says he can't implement the
> cheap move. He offers two bad choices, and misses the obvious good
> solution. All you need is a ViewPort::valid() member that is false
> after being moved-from and then say valid() is a precondition for the
> other operations on it. What's so hard about that?
How would that change the practical state of things, compared to what
Jon suggests? Ok, you have your valid() function that returns false for
a moved-from object. You still are not allowed to call any methods on
the ViewPort except destructor and assignment because now you have
valid() as a precondition everywhere. So you're back to square one, only
added a new valid() method that may be never needed by the user or the
ViewPort implementer.
I understand that the difference is in the formal contract with the
user, which is more explicitly defined. But functionally preconditions
"valid() returns true" and "not in moved-from state" are equivalent.
Neither option is safer than the other as the compiler won't
automatically test for valid(). That is unless ViewPort implementer adds
asserts or otherwise checks for the moved-from state everywhere, which
he could do with or without valid().
> Nothing in the standard's "valid but unspecified" model says types
> can't have preconditions on some operations, e.g. std::unique_ptr is
> empty after being moved-from, and that means you can't use operator*
> on it. But that's fine, because being empty is a valid state.
The difference with the standard library is very real. std::list doesn't
define any equivalent of valid() and also doesn't have a moved-from
state, which makes its move constructor potentially throwing.
>
> In a language where the compiler does not (and in general can not)
> prevent you from using a moved-from object, it isn't a good idea to
> make moved-from objects radioactive and unsafe. The reason Jon's
> argument doesn't make sense for me is because ... this is C++. We
> don't have a lifetime-checker or borrow-checker that would allow his
> desired model to work.
>
> Frankly, I struggled to find any part of the talk I agreed with.
>
> The ViewPort example is just dumb, nothing says he can't implement the
> cheap move. He offers two bad choices, and misses the obvious good
> solution. All you need is a ViewPort::valid() member that is false
> after being moved-from and then say valid() is a precondition for the
> other operations on it. What's so hard about that?
How would that change the practical state of things, compared to what
Jon suggests? Ok, you have your valid() function that returns false for
a moved-from object. You still are not allowed to call any methods on
the ViewPort except destructor and assignment because now you have
valid() as a precondition everywhere. So you're back to square one, only
added a new valid() method that may be never needed by the user or the
ViewPort implementer.
I understand that the difference is in the formal contract with the
user, which is more explicitly defined. But functionally preconditions
"valid() returns true" and "not in moved-from state" are equivalent.
Neither option is safer than the other as the compiler won't
automatically test for valid(). That is unless ViewPort implementer adds
asserts or otherwise checks for the moved-from state everywhere, which
he could do with or without valid().
> Nothing in the standard's "valid but unspecified" model says types
> can't have preconditions on some operations, e.g. std::unique_ptr is
> empty after being moved-from, and that means you can't use operator*
> on it. But that's fine, because being empty is a valid state.
The difference with the standard library is very real. std::list doesn't
define any equivalent of valid() and also doesn't have a moved-from
state, which makes its move constructor potentially throwing.
Received on 2025-04-24 18:27:10