]> git.sesse.net Git - stockfish/commitdiff
Do not assume that enum are signed
authorlucasart <lucas.braesch@gmail.com>
Mon, 3 Nov 2014 16:35:02 +0000 (00:35 +0800)
committerGary Linscott <glinscott@gmail.com>
Mon, 3 Nov 2014 16:35:02 +0000 (00:35 +0800)
Clang 3.5 issues warning on constructs like: abs(f1 - f2). The thing is that
f1 and f2 are enum types, and the range given (all positive) allows the
compiler to choose an unsigned type (efficiency being one reason to prefer
unsigned arithmetic). If f1 < f2 are unsigned, then f1 - f2 wraps around zero
and the abs() becomes a no-op. It's the reinterpretation of the unsigned
result (large value) as a signed int that happens to give the correct result,
thanks to 2's complement. This is all tricky and dangerous!

In the spirit of the standard, we assume nothing on the signedness of enums,
and simply calculate the rank and file distances as:
- rank_dist(r1, r2) = r1 < r2 ? r2 - r1 : r1 - r2
- file_dist(f1, f2) = f1 < f2 ? f2 - f1 : f1 - f2
this logic can in fact be applied to any enum we may use, so for better
generality and to avoid code duplication, we use a template function diff()
here.

No functional change.

Resolves #95

src/bitboard.h
src/endgame.cpp
src/types.h

index 6a1755b662891b26051dad911b1c42bcf2c7de86..0cf0cd0a83021bb1d0a95abdc811287abc05dea2 100644 (file)
@@ -119,11 +119,11 @@ inline int square_distance(Square s1, Square s2) {
 }
 
 inline int file_distance(Square s1, Square s2) {
 }
 
 inline int file_distance(Square s1, Square s2) {
-  return abs(file_of(s1) - file_of(s2));
+  return dist(file_of(s1), file_of(s2));
 }
 
 inline int rank_distance(Square s1, Square s2) {
 }
 
 inline int rank_distance(Square s1, Square s2) {
-  return abs(rank_of(s1) - rank_of(s2));
+  return dist(rank_of(s1), rank_of(s2));
 }
 
 
 }
 
 
index 311443ec939f82ac7b2af69c836524ba8e8768a4..2a1614af09523ffddd725e4c7fc3a1117fcecaf5 100644 (file)
@@ -479,7 +479,7 @@ ScaleFactor Endgame<KRPKR>::operator()(const Position& pos) const {
   if (   r == RANK_6
       && square_distance(bksq, queeningSq) <= 1
       && rank_of(wksq) + tempo <= RANK_6
   if (   r == RANK_6
       && square_distance(bksq, queeningSq) <= 1
       && rank_of(wksq) + tempo <= RANK_6
-      && (rank_of(brsq) == RANK_1 || (!tempo && abs(file_of(brsq) - f) >= 3)))
+      && (rank_of(brsq) == RANK_1 || (!tempo && dist(file_of(brsq), f) >= 3)))
       return SCALE_FACTOR_DRAW;
 
   if (   r >= RANK_6
       return SCALE_FACTOR_DRAW;
 
   if (   r >= RANK_6
@@ -535,7 +535,7 @@ ScaleFactor Endgame<KRPKR>::operator()(const Position& pos) const {
   {
       if (file_of(bksq) == file_of(wpsq))
           return ScaleFactor(10);
   {
       if (file_of(bksq) == file_of(wpsq))
           return ScaleFactor(10);
-      if (   abs(file_of(bksq) - file_of(wpsq)) == 1
+      if (   dist(file_of(bksq), file_of(wpsq)) == 1
           && square_distance(wksq, bksq) > 2)
           return ScaleFactor(24 - 2 * square_distance(wksq, bksq));
   }
           && square_distance(wksq, bksq) > 2)
           return ScaleFactor(24 - 2 * square_distance(wksq, bksq));
   }
@@ -749,7 +749,7 @@ ScaleFactor Endgame<KBPPKB>::operator()(const Position& pos) const {
         && opposite_colors(ksq, wbsq)
         && (   bbsq == blockSq2
             || (pos.attacks_from<BISHOP>(blockSq2) & pos.pieces(weakSide, BISHOP))
         && opposite_colors(ksq, wbsq)
         && (   bbsq == blockSq2
             || (pos.attacks_from<BISHOP>(blockSq2) & pos.pieces(weakSide, BISHOP))
-            || abs(r1 - r2) >= 2))
+            || dist(r1, r2) >= 2))
         return SCALE_FACTOR_DRAW;
 
     else if (   ksq == blockSq2
         return SCALE_FACTOR_DRAW;
 
     else if (   ksq == blockSq2
index cbef89b7f4ca3659f673b15689171caf8ffca2ab..543b38a84752faa6ab3844504e8ecd48d2aee381 100644 (file)
@@ -254,6 +254,7 @@ enum Rank {
   RANK_1, RANK_2, RANK_3, RANK_4, RANK_5, RANK_6, RANK_7, RANK_8, RANK_NB
 };
 
   RANK_1, RANK_2, RANK_3, RANK_4, RANK_5, RANK_6, RANK_7, RANK_8, RANK_NB
 };
 
+template <typename T> inline T dist(T x, T y) { return x < y ? y - x : x - y; }
 
 /// The Score enum stores a middlegame and an endgame value in a single integer
 /// (enum). The least significant 16 bits are used to store the endgame value
 
 /// The Score enum stores a middlegame and an endgame value in a single integer
 /// (enum). The least significant 16 bits are used to store the endgame value