Hereafter, we use N4140 (C++14 Standard).
According to § 17.6.3.4 Hash requirements,
The value returned shall depend only on the argument
k
for the duration of the program.[ Note: Thus all evaluations of the expression
h(k)
with the same value fork
yield the same result for a given execution of the program. — end note ]
and § 20.9.12 Class template hash says
...
the instantiation
hash<Key>
shall:(1.1) — satisfy the Hash requirements (17.6.3.4) ...
(1.2) — ...
This means a hash value of value
(i.e. hash<decltype(value)>(value)
) may take a different value if you restart the program.
But why? This limitation was not in the Standard of C++11, but in the Standard of C++14, C++17 and C++20. As a user (not a STL developer), it would be quite useful if std::hash
were deterministic. Are there any mathematical difficulties in implementing a deterministic hash function? But hash functions we daily use (e.g. deprecated md5sum
or safer sha256
) are all deterministic. Is there a problem of efficiency?
There is no need for the hash function to be deterministic between runs, but you can still provide your own hash, e.g. for unordered containers if it's a behavior you rely on.
As for why, cppreference says:
If the
Hash
requirements tells it to be deterministic, then you wouldn't be able to provide a salted hash without breaking the requirement.Here is the actual explanation why
This answer (and links in it) suggested by @NathanOliver is ultimately helpful. Let me cite important parts.
P.S.
I just googled "hash table dos" and found an informative page: The moment when you realize every server in the world is vulnerable.