]> git.sesse.net Git - stockfish/commitdiff
Fix a memcpy() warning under Valgrind
authorMarco Costalba <mcostalba@gmail.com>
Sun, 24 Oct 2010 08:15:31 +0000 (10:15 +0200)
committerMarco Costalba <mcostalba@gmail.com>
Sun, 24 Oct 2010 08:56:57 +0000 (09:56 +0100)
Fix warning: "Source and destination overlap in memcpy"

This happens when we call multiple time do_move() with the
same state, for instance when we don't need to undo the move.

This is what valgrind docs say:

You don't want the two blocks to overlap because one of them could
get partially overwritten by the copying.

You might think that Memcheck is being overly pedantic reporting this
in the case where 'dst' is less than 'src'. For example, the obvious way
to implement memcpy() is by copying from the first byte to the last.
However, the optimisation guides of some architectures recommend copying
from the last byte down to the first. Also, some implementations of
memcpy() zero 'dst' before copying, because zeroing the destination's
cache line(s) can improve performance.

In addition, for many of these functions, the POSIX standards have wording
along the lines "If copying takes place between objects that overlap,
the behavior is undefined." Hence overlapping copies violate the standard.

The moral of the story is: if you want to write truly portable code, don't
make any assumptions about the language implementation.

Signed-off-by: Marco Costalba <mcostalba@gmail.com>
src/position.cpp

index 23ffbaa46593c8dad832a7ee6ebd0973a1820228..be9ece11630d288dc264b019ec426b6e3e698d05 100644 (file)
@@ -765,7 +765,9 @@ void Position::do_move(Move m, StateInfo& newSt, const CheckInfo& ci, bool moveI
     Value npMaterial[2];
   };
 
     Value npMaterial[2];
   };
 
-  memcpy(&newSt, st, sizeof(ReducedStateInfo));
+  if (&newSt != st)
+      memcpy(&newSt, st, sizeof(ReducedStateInfo));
+
   newSt.previous = st;
   st = &newSt;
 
   newSt.previous = st;
   st = &newSt;