Recognize read access to moved-from objects as erroneous behavior. #1040
Replies: 3 comments 3 replies
-
I am on board for this until
I don't want extra annotation, dang it! But I think you don't need to do more than just assume the value as "uninitialized" on cppfront. For example, in your given scenario with The actual tricky part to me would be how to tell that the value was actually moved. Remember, The simplest way is just to assume that everything that is moved (automatically or explicitly) will be on a invalid state, but I think this would break a lot of tests, but might be worth trying... |
Beta Was this translation helpful? Give feedback.
-
I opened the issue #246 some time ago regarding this problem. |
Beta Was this translation helpful? Give feedback.
-
I actually like the idea of more marking! I like the idea of a clean 98% code with no annotations, then when something is doing something special or clever, bam a big signpost to warn you! Then that way the rest of the language can be nice and simple, because it doesn't need to cover a bunch of rare ish use cases out of the box
On 24 March 2024 15:00:01 Dylam De La Torre ***@***.***> wrote:
I am on board for this until
It is important to be able to mark
I don't want extra annotation, dang it! But I think you don't need to do more than just assume the value as "uninitialized" on cppfront. For example, in your given scenario with std::unique_ptr, if you know that moving from it would leave it empty/nullptr (so on a valid state), then why would you even check to begin with? you don't need to be able to read the state, because you already know the state. What you actually need to do is then: Be able to assert that the state is empty or valid (so allow reads of the value when asserting), and be able to write to it in a safe manner to establish invariants once more.
The actual tricky part to me would be how to tell that the value was actually moved. Remember, std::move only gives you a rvalue reference, it doesn't actually perform the move, the move is performed by the "donated to" object. For example, an int, it would just copy the value.
The simplest way is just to assume that everything that is moved (automatically or explicitly) will be on a invalid state, but I think this would break a lot of tests, but might be worth trying...
—
Reply to this email directly, view it on GitHub<#1040 (comment)>, or unsubscribe<https://github.com/notifications/unsubscribe-auth/AALUZQOSCK734AZAPLYLJBLYZ3S65AVCNFSM6AAAAABFFUPMHGVHI2DSMVQWIX3LMV43SRDJONRXK43TNFXW4Q3PNVWWK3TUHM4DQOJTGM2TS>.
You are receiving this because you are subscribed to this thread.Message ID: ***@***.***>
|
Beta Was this translation helpful? Give feedback.
-
Motivation
Accessing a moved-from object may yield in unexpected results. The standard requires in [lib.types.movedfrom]
So unless otherwise specified a move may leave the object in a state the makes it unfit for further use unless a known state is established again.
In his last blog post Herb mentions P2795R5 “Erroneous behavior for uninitialized reads” which introduces erroneous behaviour as a concept in the C++ standard. The focus there is read access of uninitialized variables.
I would argue that read access to moved-from object is erroneous behaviour unless the access is declared well specified by the type.
Consider Compiler Explorer
The uninitialized variable will in Cpp1 be recognized as erroneous behaviour since erverything is well defined from a language position but it is still problematic since the value might not be what the user expected.
In Cpp2 this will already result in an error message:
Now consider:
Here the variable 'answer' was correctly initialized but later moved from. The read access will result might result in something unexpected.
Proposal
Objects that are moved-from should be regarded as uninitialized and read access should be considered erroneous unless marked as safe.
It is important to be able to mark safe access for types that provide guarantees for moved-from like unique pointers that will return nullptr after being moved-from or vector where the access to
size()
is safe but access to an index might no longer be safe. After a callsize()
the current state of the vector is known to be empty. Such members could be attibuted asperemptory
meaning arrogant self-assurance or similar.A moved-from object can be considered in a known state (i.e. not uninitialized) after it got accessed through a non-const or a 'safe to access after move' member.
Beta Was this translation helpful? Give feedback.
All reactions