web-dev-qa-db-fra.com

Puis-je appeler memcpy () et memmove () avec "nombre d'octets" mis à zéro?

Dois-je traiter les cas lorsque je n'ai réellement rien à déplacer/copier avec memmove()/memcpy() comme cas Edge

int numberOfBytes = ...
if( numberOfBytes != 0 ) {
    memmove( dest, source, numberOfBytes );
}

ou devrais-je simplement appeler la fonction sans vérifier

int numberOfBytes = ...
memmove( dest, source, numberOfBytes );

La vérification dans l'ancien extrait est-elle nécessaire?

89
sharptooth

De la norme C99 (7.21.1/2):

Où un argument déclaré comme size_t n spécifie la longueur du tableau pour une fonction, n peut avoir la valeur zéro lors d'un appel à cette fonction. Sauf indication contraire explicite dans la description d'une fonction particulière du présent paragraphe, les arguments de pointeur sur un tel appel doivent toujours avoir des valeurs valides, comme décrit au 7.1.4. Lors d'un tel appel, une fonction qui localise un caractère ne trouve aucune occurrence, une fonction qui compare deux séquences de caractères renvoie zéro et une fonction qui copie des caractères copie zéro caractère.

Donc la réponse est non; la vérification n'est pas nécessaire (ou oui; vous pouvez passer à zéro).

127
Mike Seymour

Comme l'a dit @You, la norme spécifie que memcpy et memmove doivent gérer ce cas sans problème; car ils sont généralement mis en œuvre en quelque sorte comme

void *memcpy(void *_dst, const void *_src, size_t len)
{
    unsigned char *dst = _dst;
    const unsigned char *src = _src;
    while(len-- > 0)
        *dst++ = *src++;
    return _dst;
}

vous ne devriez même pas avoir de pénalité de performance autre que l'appel de fonction; si le compilateur prend en charge intrinsèques/inlining pour de telles fonctions, la vérification supplémentaire peut même rendre le code un tout petit peu plus lent, car la vérification est déjà effectuée en même temps.

4
Matteo Italia