Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

std::map operator [] -- undefined behaviour?

I've just stuck myself with the following question: should this cause undefined behaviour or not and why?

std::map<int, int> m;
m[10] += 1;

It compiles and runs perfectly but it doesn't prove anything. It resembles a common UB example i = ++i + i++; since operator[] does have side effects but on the other hand assuming any order of evaluation (left to right and right to left) brings me to the same final state of the map

P.S. possibly related: http://en.cppreference.com/w/cpp/language/eval_order

edit

Sorry guys I should have written

 m[10] = m[10] + 1;
like image 503
DimG Avatar asked Jun 03 '16 12:06

DimG


People also ask

What is C++ undefined Behaviour?

So, in C/C++ programming, undefined behavior means when the program fails to compile, or it may execute incorrectly, either crashes or generates incorrect results, or when it may fortuitously do exactly what the programmer intended.

What happens if key doesn't exist in map?

The map::operator[] searches the data structure for a value corresponding to the given key, and returns a reference to it. If it can't find one it transparently creates a default constructed element for it.

What does Hashmap return if key not found C++?

map find() function in C++ STL If the key is not present in the map container, it returns an iterator or a constant iterator which refers to map.

What is std::map in C++?

(since C++17) std::map is a sorted associative container that contains key-value pairs with unique keys. Keys are sorted by using the comparison function Compare . Search, removal, and insertion operations have logarithmic complexity. Maps are usually implemented as red-black trees.


1 Answers

There is nothing undefined about this. The operator[] returns an lvalue reference to the map entry (which it creates if necessary). You are then merely incrementing this lvalue expression, i.e. the underlying entry.

The rules for evaluation order state that for a modifying assign operation, the side effect is sequenced strictly after the evaluation of both the left (i.e. lvalue reference to the map entry) and right (i.e. the constant 1) operands. There is no ambiguity at all in this example.

UPDATE: In your updated example nothing changes. Again the side effect of modifying m[10] is sequenced strictly after the other operations (i.e. evaluating as an lvalue on the right, evaluating it on the right, and performing the addition).

The relevant sequencing rule, from cppreference:

8) The side effect (modification of the left argument) of the built-in assignment operator and of all built-in compound assignment operators is sequenced after the value computation (but not the side effects) of both left and right arguments, and is sequenced before the value computation of the assignment expression (that is, before returning the reference to the modified object)

like image 60
Smeeheey Avatar answered Oct 15 '22 20:10

Smeeheey