This results in a SEGFAULT when accessing unique_ptr->get_id() as release() is run beforehand.
Is the ordering not guaranteed here?
#include <iostream>
#include <memory>
#include <unordered_map>
class D
{
private:
int id_;
public:
D(int id) : id_{id} { std::cout << "D::D\n"; }
~D() { std::cout << "D::~D\n"; }
int get_id() { return id_; }
void bar() { std::cout << "D::bar\n"; }
};
int main() {
std::unordered_map<int, D*> obj_map;
auto uniq_ptr = std::make_unique<D>(123);
obj_map[uniq_ptr->get_id()] = uniq_ptr.release();
obj_map.at(123)->bar();
return 0;
}
>Solution :
This is because of [expr.ass]/1 which states:
[…] In all cases, the assignment is sequenced after the value computation of the right and left operands, and before the value computation of the assignment expression. The right operand is sequenced before the left operand. With respect to an indeterminately-sequenced function call, the operation of a compound assignment is a single evaluation.
emphasis mine
According to the above the right hand side gets evaluated first, then the left hand side, then the assignment happens. It should be noted that this is only guaranteed since C++17. Before C++17 the order of the left and right sides evaluations was unspecified.