mirror of
https://github.com/HChaZZY/Stockfish.git
synced 2025-12-21 01:27:16 +08:00
Fix reading of book file
Bug is subtle because appears only under MSVC 32 bits in optimized version, hence was missed before. Bug is due to the fact that evaluation order of terms of a sum is undefined by the standard, so in get_int() we have: return 256 * get_int<n-1>() + bookFile.get(); And if get() is evaluated before get_int() we have a corrupted key. The patch rewrites the code in a more natural and predictable way. No functional change. Signed-off-by: Marco Costalba <mcostalba@gmail.com>
This commit is contained in:
17
src/book.cpp
17
src/book.cpp
@@ -502,6 +502,18 @@ int Book::find_entry(uint64_t key) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// Book::get_number() reads sizeof(T) chars from the file's binary byte
|
||||||
|
/// stream and converts them in a number of type T.
|
||||||
|
template<typename T>
|
||||||
|
void Book::get_number(T& n) {
|
||||||
|
|
||||||
|
n = 0;
|
||||||
|
|
||||||
|
for (size_t i = 0; i < sizeof(T); i++)
|
||||||
|
n = (n << 8) + (T)bookFile.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/// Book::read_entry() takes an integer index, and returns the BookEntry
|
/// Book::read_entry() takes an integer index, and returns the BookEntry
|
||||||
/// at the given index in the book file.
|
/// at the given index in the book file.
|
||||||
|
|
||||||
@@ -514,7 +526,10 @@ BookEntry Book::read_entry(int idx) {
|
|||||||
|
|
||||||
bookFile.seekg(idx * sizeof(BookEntry), ios_base::beg);
|
bookFile.seekg(idx * sizeof(BookEntry), ios_base::beg);
|
||||||
|
|
||||||
*this >> e.key >> e.move >> e.count >> e.learn;
|
get_number(e.key);
|
||||||
|
get_number(e.move);
|
||||||
|
get_number(e.count);
|
||||||
|
get_number(e.learn);
|
||||||
|
|
||||||
if (!bookFile.good())
|
if (!bookFile.good())
|
||||||
{
|
{
|
||||||
|
|||||||
11
src/book.h
11
src/book.h
@@ -48,12 +48,7 @@ public:
|
|||||||
const std::string name() const { return bookName; }
|
const std::string name() const { return bookName; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// read n chars from the file stream and converts them in an
|
template<typename T> void get_number(T& n);
|
||||||
// integer number. Integers are stored with highest byte first.
|
|
||||||
template<int n> uint64_t get_int();
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
Book& operator>>(T& n) { n = (T)get_int<sizeof(T)>(); return *this; }
|
|
||||||
|
|
||||||
BookEntry read_entry(int idx);
|
BookEntry read_entry(int idx);
|
||||||
int find_entry(uint64_t key);
|
int find_entry(uint64_t key);
|
||||||
@@ -64,8 +59,4 @@ private:
|
|||||||
RKISS RKiss;
|
RKISS RKiss;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Yes, we indulge a bit here ;-)
|
|
||||||
template<int n> inline uint64_t Book::get_int() { return 256 * get_int<n-1>() + bookFile.get(); }
|
|
||||||
template<> inline uint64_t Book::get_int<1>() { return bookFile.get(); }
|
|
||||||
|
|
||||||
#endif // !defined(BOOK_H_INCLUDED)
|
#endif // !defined(BOOK_H_INCLUDED)
|
||||||
|
|||||||
Reference in New Issue
Block a user