Sie können diese Verwendung memmove
auch in Git 2.14.x (Q3 2017) berücksichtigen.
Siehe Commit 168e635 (16. Juli 2017) und Commit 1773664 , Commit f331ab9 , Commit 5783980 (15. Juli 2017) von René Scharfe ( rscharfe
) .
(Zusammengeführt von Junio C Hamano - gitster
- in Commit 32f9025 , 11. August 2017)
Es verwendet ein Hilfsmakro,MOVE_ARRAY
das die Größe basierend auf der für uns angegebenen Anzahl von Elementen berechnet und NULL
Zeiger unterstützt, wenn diese Anzahl Null ist.
Rohe memmove(3)
Aufrufe mit NULL
können dazu führen, dass der Compiler (zu eifrig) spätere NULL
Überprüfungen optimiert .
MOVE_ARRAY
Fügt einen sicheren und praktischen Helfer zum Verschieben potenziell überlappender Bereiche von Array-Einträgen hinzu.
Es leitet die Elementgröße ab, multipliziert automatisch und sicher, um die Größe in Bytes zu erhalten, führt eine grundlegende Typensicherheitsprüfung durch Vergleichen der Elementgrößen durch und memmove(3)
unterstützt im Gegensatz dazu NULL
Zeiger, wenn 0 Elemente verschoben werden sollen.
#define MOVE_ARRAY(dst, src, n) move_array((dst), (src), (n), sizeof(*(dst)) + \
BUILD_ASSERT_OR_ZERO(sizeof(*(dst)) == sizeof(*(src))))
static inline void move_array(void *dst, const void *src, size_t n, size_t size)
{
if (n)
memmove(dst, src, st_mult(size, n));
}
Beispiele :
- memmove(dst, src, (n) * sizeof(*dst));
+ MOVE_ARRAY(dst, src, n);
Es verwendet das Makro,BUILD_ASSERT_OR_ZERO
das eine Abhängigkeit von @cond
der Erstellungszeit behauptet, als Ausdruck (wobei dies die Bedingung für die Kompilierungszeit ist, die wahr sein muss).
Die Kompilierung schlägt fehl, wenn die Bedingung nicht erfüllt ist oder vom Compiler nicht ausgewertet werden kann.
#define BUILD_ASSERT_OR_ZERO(cond) \
(sizeof(char [1 - 2*!(cond)]) - 1)
Beispiel:
#define foo_to_char(foo) \
((char *)(foo) \
+ BUILD_ASSERT_OR_ZERO(offsetof(struct foo, string) == 0))