-
Notifications
You must be signed in to change notification settings - Fork 49
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix mutant_relation::operator=. #45
Conversation
Better to not use |
Hi Ignacy and Peter, my analysis of the problem and the (partial) fix follows. Original test case pasted here for convenience: #include <cassert>
#include <boost/bimap.hpp>
#include <boost/bimap/unordered_set_of.hpp>
int main()
{
using map_type = boost::bimap<boost::bimaps::set_of<int>,
boost::bimaps::unordered_set_of<int>>;
map_type map;
auto x = map.insert({0, 0}).first;
map.replace_right(x, 42);
auto y = map.find(map_type::value_type{0, 42});
assert(y != map.end());
assert(x == y);
assert(&x->right == &y->right);
assert(y->right != 0);
assert(x->right != 0);
}
bool replace_(const value_type& v,index_node_type* x,lvalue_tag)
{
x->value()=v;
return true;
}
Nitpick: your code is tab-indented, please replace with spaces, thank you! |
Defining template <bool FM> mutant_relation& operator=(const mutant_relation<TA, TB, Info, FM>& rel) { base_::change_to(rel); return *this; } does not prevent the compiler from implicitly providing mutant_relation& operator=(const mutant_relation&); and hence the implicit version takes over when FM == force_mutable and does not call base_::change_to. Replace the template version with two non-template overloads, both calling base_::change_to. Signed-off-by: Ignacy Gawędzki <[email protected]>
The fact that this behaves strangely doesn't necessarily imply a compiler bug, especially if the code violates strict aliasing rules. As I see it, there are various places in Bimap and Multi-Index code where strict aliasing violation warnings are purposefully disabled and a few reinterpret_cast-based hacks are performed.
You're right, the code is supposed to be equivalent, but first, GCC with -Wdeprecated-copy (which is enabled with -W) warns on the lack of explicitly defined assignment operator as being deprecated (because a copy constructor has been explicitly defined), and second, apparently GCC generates different code depending on there being an explicit assignment operator defined or not.
Okay, I'm fixing that right away. |
Closing/reopening to retrigger CI. |
Defining
does not prevent the compiler from implicitly providing
and hence the implicit version takes over when
FM == force_mutable
and does not callbase_::change_to
.Replace the template version with two non-template overloads, both calling
base_::change_to
.Apparently fixes #43.This makes issue #43 only go away on x86_64, but it is still present on aarch64 when compiling with at least -O2.