I just found a bug in my code that depends on the order the elements are stored in an unordered_map. Ok not a big deal, I’m going to fix it. My question is only out of curiosity to understand different implementations in different compilers.
When compiled on my computer (linux g++) my unit tests always works because the unordered_map is ordered always the same and the order does not trigger my bug.
When compiled on another computer and architecture (mac M1, clang++) my bug is always triggered because the elements always come in the same order, which is different from with g++.
When compiler on my computer with clang++: no bug.
In my specific case the key of the unordered_map is an int and the hash is the default one for an int I did not used a custom hash function.
My questions are thus: how the order of an unorderd_map depend on the compiler implementation? I’ve always assumed it was somewhat random, but I was wrong, it is stable for each compiler I tested. What the standard says about that? What are the typical implementations to order an unordered_map?
>Solution :
The hash function determines in which bucket an element gets placed. std::unordered_map<Key,T> uses std::hash<Key> as default hasher. From cppreference:
The actual hash functions are implementation-dependent and are not required to fulfill any other quality criteria except those specified above. Notably, some implementations use trivial (identity) hash functions which map an integer to itself. In other words, these hash functions are designed to work with unordered associative containers, but not as cryptographic hashes, for example.
And that implies that the resulting order you get depends on the implementation.
I assumed that hashing an int was somehow standard.
Implementation defined is "somehow standard" ;). Hash functions is still topic of research. Choosing an optimal hash is not simple and it would bad if the standard would fix one particular hash that is state of the art now, but outdated in a year or so.