Summary: | Move constructors are not noexcept | ||||||
---|---|---|---|---|---|---|---|
Product: | Eigen | Reporter: | Martinho Fernandes <martinho.fernandes> | ||||
Component: | General | Assignee: | Nobody <eigen.nobody> | ||||
Status: | RESOLVED FIXED | ||||||
Severity: | Unknown | CC: | gael.guennebaud, jacob.benoit.1, marton78 | ||||
Priority: | Normal | ||||||
Version: | 3.2 | ||||||
Hardware: | All | ||||||
OS: | All | ||||||
Whiteboard: | |||||||
Bug Depends on: | |||||||
Bug Blocks: | 558 | ||||||
Attachments: |
|
Description
Martinho Fernandes
2014-01-09 18:26:01 UTC
Test case: #include <Eigen/Core> #include <utility> #include <vector> using namespace Eigen; // a type containing an eigen member to showcase // that providing a noexcept move constructor is needed struct B { B(const Array2i& x) : x(x) {} // [1]: the next line shouldn't be necessary! B(B&& b) noexcept : x(b.x) {} Array2i x; }; // a move-only type struct M { explicit M(int a) : a(a) {} M(M&& m) noexcept : a(m.a) {} int a; }; typedef std::pair<M, B> pair; typedef std::vector<pair, aligned_allocator<pair>> vector; int main() { vector v; v.emplace_back(M(0), B(Array2i(1,2))); return 0; } std::vector requires noexcept moves in move-only types. Because of M, the pair is also move-only. With noexcept move constructors in eigen types, this should compile fine without the line [1]. Created attachment 416 [details]
This patch remedies the issue
This patch qualifies move constructors and move assignment operators (MC/MAO) as noexcept.
Note that the exception safety of the MC/MAO is not trivial to determine. Namely, the call to Base::_set_noalias(other) is problematic for custom scalar types for which assignment may throw. Hence I only marked the MC/MAO of Array and Matrix as noexcept iff std::is_nothrow_move_assignable<Scalar>::value is true. Maybe somebody who is knowledgeable in the inner workings of internal::assign_selector could comment on whether this guess is correct.
The patch applies on top of pull request #40, which is (mysteriously to me) also required to fix this issue.
Note that these patches apply nicely on top of 3.2 by first grafting https://bitbucket.org/eigen/eigen/commits/c280e906ade1689d2f47c14d40e820a8e6cc2de4 Reviving this old bug. Could it by chance be merged into the next release? With C++11 gaining more and more acceptance, having Eigen not fully support it is becoming an issue. It seems very unlikely that is_nothrow_move_assignable<Scalar> could be the right condition for a move constructor... Yep, is_nothrow_move_constructible would be more appropriate. With such a change, I'd be OK to apply this patch. https://bitbucket.org/eigen/eigen/commits/9d4a08d57d0d/ Summary: Bug 725: make move ctor/assignment noexcept. -- GitLab Migration Automatic Message -- This bug has been migrated to gitlab.com's GitLab instance and has been closed from further activity. You can subscribe and participate further through the new bug through this link to our GitLab instance: https://gitlab.com/libeigen/eigen/issues/725. |