Sie können diese Verwendung memmoveauch 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 NULLkönnen dazu führen, dass der Compiler (zu eifrig) spätere NULLÜberprüfungen optimiert .
MOVE_ARRAYFü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 NULLZeiger, 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 @condder 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))