Opened 5 years ago
Closed 5 years ago
#13420 closed Bugs (invalid)
small_vector - invalid move constructor/move assignment for size < N
Reported by: | Antervis | Owned by: | Ion Gaztañaga |
---|---|---|---|
Milestone: | To Be Determined | Component: | container |
Version: | Boost 1.66.0 | Severity: | Problem |
Keywords: | small_vector, move | Cc: | Russkov.AD@… |
Description
When small_vector is move-constructed or move-assigned from another small_vector, the initial one has elements moved out, but vector size is left unchanged. This only happens if internal vector memory is used (vector size is less than in-place capacity N)
small_vector<int, 5> a = {1,2,3}; small_vector<int, 5> b = std::move(a); // after the assignment, a.size() is 3
Detailed example is here.
Change History (4)
comment:1 by , 5 years ago
Version: | Boost 1.65.0 → Boost 1.66.0 |
---|
follow-up: 3 comment:2 by , 5 years ago
comment:3 by , 5 years ago
Replying to Ion Gaztañaga:
There is not requirement that a move constructor or assignment must empty the source. Source must be in a consistent but unspecified state.
even though current behavior is standard-conforming, it is certainly inconsistent both with standard containers (which are empty after being moved out) and with itself (moved out state depends on initial state). I personally don't see a reason for this behavior to be an intended design choice and I suggest it to be changed
comment:4 by , 5 years ago
Resolution: | → invalid |
---|---|
Status: | new → closed |
I've reviewed some STL implementations, specifically operator=(vector&&source), the case when the allocator shall not be propagated allocator_traits::propagate_on_container_move_assignment or allocators don't compare equal. In those cases memory can't be stolen from the source container and elements are move constructed from source to destination.
- libstdc++ clears the source vector
- libc++ and msvc don't clear the source vector (size is unchanged)
The standard says for operator=(vector&&) (the move constructor always transfers the allocator and does not support different storage types for source and destination like small_vector) that *this shall have the same value "source" had but no guarantee about the state of "source".
So I'm reluctant to change the implementation to clear the source. If many users find this annoying then we will reopen the issue. Thanks for the report.
There is not requirement that a move constructor or assignment must empty the source. Source must be in a consistent but unspecified state.