131 votes

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

Dois-je traiter des cas alors que je n'ai rien à déplacer / copier avec memmove() / memcpy() comme cas extrêmes?

 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 );
 

Le chèque dans l'ancien extrait est-il nécessaire?

173voto

Mike Seymour Points 130519

À partir du standard C99 (7.21.1/2):

Lorsqu'un argument déclarée size_t n spécifie la longueur du tableau pour un fonction, n peut avoir la valeur zéro sur un appel à cette fonction. Sauf mention explicite sinon dans la description d'une fonction spécifique dans cette subdivision, pointeur arguments sur un tel appel doit toujours avoir des valeurs valides, comme décrit dans 7.1.4. Sur un tel appel, un fonction qui permet de localiser un personnage ne trouve aucune occurrence, une fonction qui compare deux les séquences de caractères renvoie zéro, et une fonction qui copie les caractères des copies de zéro des personnages.

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

10voto

You Points 8861

La documentation de l' memmove et memcpy dit ceci:

La fonction ne vérifie pas pour n'importe quel caractère de fin null dans la source - il toujours des copies exactement num octets.

Le opengroup documentation dit essentiellement la même chose.

Donc, vu qu'il copie "exactement num octets", copie zéro octets lors de la num = 0, et donc il ne devrait pas être nécessaire de traiter cela comme un cas particulier.

6voto

Matteo Italia Points 53117

Comme le 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 les fonctions intrinsèques / en ligne pour de telles fonctions, la vérification supplémentaire peut même ralentir légèrement le code, car la vérification est déjà effectuée au même moment.

2voto

unwind Points 181987

Non, le chèque n'est pas nécessaire. Compter sur zéro pour être traité correctement est correct et très raisonnable, à mon avis. Cela vaut peut-être la peine de commenter.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X