edit: this question should have not been closed, if you look at the answers you will see they are totally different(old question has no mention of C++17).
I was reading a PVS blog post where they mention the following bug.
(reduced)
std::map<int,int> m;
m[7]=5;
auto val = 15;
if (!m.contains(val)){
m[val] = m.size(); // bug here
}
According to blog post this is buggy. I always thought that operator [] call for map is a function call so .size() is sequenced before [] because functions act as sequence point.
So why is this a bug?
note: I know sequence points do not exist since C++11, but I use them since new wording is much harder for me to understand.
Pre C++17
and 5.17 [expr.ass] doesn't mention any sequencing between the operands of built-in assignment. So the evaluation of the two operands of the built-in assignment operator
=is unsequenced with regards to each other.m[val]andm.size()can be evaluated in any order (can even overlap - interleaved the CPU instructions).Considering:
m[val]has a side effect of modifying the map's size (a scalar)the value computation of
m.size()accesses the map's sizeSo yes, the behavior is indeed Undefined.
C++17
So the behavior is defined.
m.size()will be evaluated beforem[val]