También puede considerar este uso memmove
visto en Git 2.14.x (Q3 2017)
Consulte la confirmación 168e635 (16 de julio de 2017) y la confirmación 1773664 , la confirmación f331ab9 y la confirmación 5783980 (15 de julio de 2017) de René Scharfe ( rscharfe
) .
(Combinado por Junio C Hamano - gitster
- en el compromiso 32f9025 , 11 de agosto de 2017)
Utiliza una macro auxiliarMOVE_ARRAY
que calcula el tamaño en función del número especificado de elementos para nosotros y admite NULL
punteros cuando ese número es cero.
Las memmove(3)
llamadas sin procesar con NULL
pueden hacer que el compilador optimice (demasiado ansiosamente) las NULL
comprobaciones posteriores .
MOVE_ARRAY
agrega un ayudante seguro y conveniente para mover rangos potencialmente superpuestos de entradas de matriz.
Infiere el tamaño del elemento, se multiplica de forma automática y segura para obtener el tamaño en bytes, realiza una verificación de seguridad de tipo básica comparando los tamaños de los elementos y, a diferencia de memmove(3)
, admite NULL
punteros si se deben mover 0 elementos.
#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));
}
Ejemplos :
- memmove(dst, src, (n) * sizeof(*dst));
+ MOVE_ARRAY(dst, src, n);
Utiliza la macroBUILD_ASSERT_OR_ZERO
que afirma una dependencia en tiempo de compilación, como expresión ( @cond
siendo la condición en tiempo de compilación que debe ser verdadera).
La compilación fallará si la condición no es verdadera o el compilador no puede evaluarla.
#define BUILD_ASSERT_OR_ZERO(cond) \
(sizeof(char [1 - 2*!(cond)]) - 1)
Ejemplo:
#define foo_to_char(foo) \
((char *)(foo) \
+ BUILD_ASSERT_OR_ZERO(offsetof(struct foo, string) == 0))