0
votes

I'm using boost::hash_combine in a custom hash object for a std::array defining a position in a two-dimensional grid.

struct PositionHasher {
    std::size_t operator()(const std::array<int, 2> &position) const {
        std::size_t seed;
        boost::hash_combine(seed, position[0]);
        boost::hash_combine(seed, position[1]);
        return seed;
    };
};

The calls to boost::hash combine are equivalent to:

seed ^= position[0] + 0x9e3779b9 + (seed << 6) + (seed >> 2);
seed ^= position[1] + 0x9e3779b9 + (seed << 6) + (seed >> 2);

When building my app in release mode, I get different hashing behaviour than in debug mode. I suspect that I in fact get different has values for the same std::array objects. This behaviour persists even if I remove the 0x9e3779b9 from the function.

How is this possible? I'm using VS2015 and full /Ox optimisation, and I'm using the custom hash to lookup the position objects in a std::unordered_set.

1
Where's the minimal self-contained example that actually exhibits this behaviour? Anyways, you shouldn't depend on hashing to be portable. It may differ across runs. That's often a security featuresehe
Fair enough, I'll try to come up with an example. In the meantime, any ideas on this behaviour are appreciated.Chris

1 Answers

1
votes

I found the bug - a silly mistake, but maybe the solution proves helpful for others: as you can see in the code above, I did not initialise the std::size_t variable for the seed. In debug mode, it's initialised by default to 0. However, this does not happen under optimisation, leading to inconsistent behaviour / different hashes for the same data.

More information on bugs that tend to happen in release mode: Common reasons for bugs in release version not present in debug mode