Part of my program does something like this:
#include <unordered_set>
#include <unordered_map>
std::unordered_map<std::string, int> G{{"1", 10}};
int m(const std::string& i, std::unordered_set<std::string>& v) {
v.erase(i);
return G.at(i);
}
int main() {
std::unordered_set<std::string> v {"1"};
const std::string& remove_this = *v.begin();
return m(remove_this, v);
}
The program should be portable between linux and windows. When compiled with g++, the program runs well and returns 10, as expected. However, when compiled with VS 2017, the programs aborts, throwing an std::out_of_range. With most trivial effort of debugging, I see that i in function m is destroyed before the call to G.at. (both without optimizations)
To my understanding, the const reference to v.begin() should expire until m returns (the g++ case). But it MSVC obviously didn't agree with that.
Is this undefined behavior or implementation defined? When, indeed, does an argument passed by const reference expire then?
The argument
ilives untilmends. However, the object thatireferences disappears afterv.erase(i), leavingias a dangling reference.G.at(i)then reads from the dangling reference causing undefined behavior.