To do what? The restriction comes from the algorithm, and from my (I'll be conservative here saying "my" and not "chess") algorithm point of view, nothing should be done with that entry, except "replace". So I still don't see the point.matthewlai wrote:The pointer may be useless for now, but you may not remember the fact that it needs to be useless, and decide to use it again later, after you have completely forgotten the restriction.
Again there is no room for reading something after a search.There is a reason to reuse it. Conceptually, when you are reading the code, you are thinking of the pointer as a pointer to the entry corresponding to this position. If you want to write something about this position into the entry, it makes perfect sense to do it through the pointer. If you don't want to allow that, you can make the probing function return a const pointer. However, even in that case, if you decide to read something else from it after a search, it would still be buggy.
+1This is also very dangerous if you are not the only developer on the project. Other developers may not be aware of such a restriction, and they may decide to use it.
I try to be more explicit. IN THE Folkert IMPLEMENTATION there are no multilple buckets for the same hash index, so one hash key will ALWAYS map to the SAME memory address (hash % nEntry). Now when I decide to use my pointer:And here you see just how easy it is to make a mistake in this case.
The pointer is not tied to the hash key (as you would conceptually expect from reading the code). It is tied to the hash slot.
By the time you access it again, it may have a different hash key already, from a different position that mapped to the same slot. The slot may now belong to another position. Anything you read from it may be wrong, and anything you write to it will overwrite something that you probably did not intend to overwrite.
1) the TT entry is still the same entry (entryes[hash % nEntry].hash == hash), but I overwrite the entry. No problems at all.
2) the TT entry belongs to another position (entryes[hash % nEntry].hash != hash). First question: how it is possible in a single-threaded search? BTW, I should use the entry (that is a replace operation) .... Uhm... Replacement scheme:
2a) always replace: I replace it, stop. No matter what's inside the TT entry. No prolems.
2b) depth preferred: I have to decide if replace the entry or not. So I read through the pointer, or from some other means, but I will actually end up reading the exact SAME entry from the exact SAME memory address. So no different behaviour.
Now, in a TT implementation with multiple buckets per hash index, this is a bit different because an hash key can map to different hash buckets at different addresses, and there is "space" between the READ use of the hash entry (beginning of the search function) and the WRITE use (the end of the search, or at least after a subtree search), and this can change the content of the buckets at the same hash index, making a store through the pointer a very bad decision.
And of course, in a multithreaded search something more can happen, something so weird that your TT entry will change under your compiler's feet between the two 8 bytes read, as Bob said.