MISRA C++:2023 Rule 28.6.3
Description
Rule Definition
An object shall not be used while in a potentially moved-from state. 1
Rationale
If you convert an lvalue reference to rvalue reference by using
std::move() or std::forward, the original
lvalue reference remains in a potentially moved-from state, which can be an
indeterminate state. In this code, the object original is passed as
an lvalue reference to foo(), which converts the lvalue reference to
an rvalue reference:
class myobj {/**/
};
void foo(myobj &A) {
myobj B{std::move(A)}
}
void bar() {
myobj original;
foo(original)
}foo() is called the object
original is in an indeterminate state. Using the
original object can have unexpected results.Avoid using objects while they are in a potentially moved-from state. If your function accepts a lvalue reference, avoid keeping them in a move-from state when the function returns.
This rule does not apply when:
You use a
std::unique_ptr. The mover-from state ofstd::unique_ptris well-defined and equal tonullptr.You assign a value to the potentially moved-from object.
You destroy the potentially moved-from object.
Polyspace Implementation
The rule checker reports a violation of this rule if any of these conditions are true:
An object is read after its contents are moved to a destination object by calling the
std::movefunction explicitly.An object forwarded by explicitly calling
std::forwardis reused after the call. Polyspace® does not flag the call tostd::forwardif its argument is reused in a branch that cannot be reached after the call tostd::forward. For example, in this code snippet, the branch where the reuse of variabletoccurs cannot be reached after the execution enters the branch wherestd::forwardis used.template<typename T> void func(T&& t) { T&& p = t; switch(t) { case 0: p = std::forward<T>(t); break; case 1: t--; //t reused break; } }An lvalue reference parameter of a function is moved-from in the function body.
Polyspace does not flag accessing a source object after its contents are moved if any of these conditions are true:
The source object of an explicit move operation is one of these types:
std::unique_ptrstd::shared_ptrstd::weak_ptrstd::basic_iosstd::basic_filebufstd::threadstd::unique_lockstd::shared_lockstd::promisestd::futurestd::shared_futurestd::packaged_taskstd::vector
The move operation is performed implicitly. For example, the function
std::removemoves objects implicitly. Polyspace does not flag accessing the object moved implicitly. To avoid accidentally accessing a moved object, erase the removed object by usingstd::erase. For details about usingstd::remove, seeImproper erase-remove idiom.The source object is of a built-in base type, such as:
int,enum,float,double,std::intptr_t,std::nullptr_t, and pointer types.
Troubleshooting
If you expect a rule violation but Polyspace does not report it, see Diagnose Why Coding Standard Violations Do Not Appear as Expected.
Examples
Check Information
| Group: Algorithms Library |
| Category: Required |
Version History
Introduced in R2024b
1 All MISRA coding rules and directives are © Copyright The MISRA Consortium Limited 2021.
The MISRA coding standards referenced in the Polyspace Bug Finder™ documentation are from the following MISRA standards:
MISRA C:2004
MISRA C:2012
MISRA C:2023
MISRA C++:2008
MISRA C++:2023
MISRA and MISRA C are registered trademarks of The MISRA Consortium Limited 2021.