struct Obj
{
int foo;
bool bar;
}
then we were storing those in a custom hashmap using these as keys, where the hashing function was basically hashing bits of each stored object, without any awareness of what's in the object.The bug was found when someone did something like:
void DoSomething(Obj obj)
{
if(!map.has(obj))
map.add(obj, new Whatever());
map[obj].blah(); //CRASH null pointer exception
}
I was like.....well, if there is no key "obj" in the map, we insert one....and yet literally one line after it doesn't have a value for that key??? How can this be?Well, it can be because even though the struct looks like it takes 5 bytes, in reality it's 8 bytes because it's getting padded. So a naive hashing method that just looks at bits is hashing your 5 bytes of actual data + 3 bytes of garbage, which means that two "identical" objects are very unlikely to actually produce the same hash.
C++20 now has a "hashable" concept to help with this, but it still requires the programmer to be aware of structure packing.