2008-11-21 3 views

Répondre

51

La fonction avec un paramètre utilisé peut avoir un vrai bogue dans les cas suivants:

  1. Il y a une sortie paramètre, qui n'est pas attribué ou écrit dans, ce qui entraîne de la valeur définie pour la votre interlocuteur.

  2. L'un des paramètres est un pointeur de fonction de rappel que vous devez appeler et oublier de le faire. Peut se produire s'il y a beaucoup de #ifdef s dans la fonction.

  3. Vous déclarez une variable locale du même nom qui masque un paramètre et utilise par la suite la mauvaise valeur dans la fonction.

Ne pas utiliser une entrée paramètres peuvent être inoffensifs, mais vous pouvez réduire le bruit pour voir les avertissements utiles en cochant les paramètres d'entrée non utilisés explicitement au début de la fonction par coulée à void (fonctionne pour à la fois C et C++):

(void)param1; 

Ou,

#define UNUSED(expr) do { (void)(expr); } while (0) 
... 

void foo(int param1, int param2) 
{ 
    UNUSED(param2); 
    bar(param1); 
} 

ou d'omettre le nom de paramètre (C++ uniquement):

void foo(int param1, int /*param2*/) 
{ 
    bar(param1); 
} 
+5

Par ailleurs, l'approche avec la macro UNUSED est utilisée dans la bibliothèque Qt: elle a un Q_UNUSED, qui fait exactement la même chose, mais sans wrapper "do..while". –

+0

En effet, il ressemble à un idiome commun. Je l'ai vu dans quelques endroits. –

+0

Pourriez-vous ajouter un exemple de la façon d'effectuer un cast sur void? (Je l'ai essayé et cela fonctionne, mais il semble si bizarre que je n'aurais jamais pensé qu'il compilerait - et je suis sûr que d'autres ressentent la même chose.) –

1

Aucune. sauf [EDIT]: comme d'autres l'ont souligné, vous pourriez avoir un paramètre de sortie non assigné. Vous devriez les nettoyer, car à maintes reprises j'ai vu des développeurs ignorer des avertissements importants qui étaient cachés parmi un grand nombre d'avertissements, et ils étaient tellement habitués à voir les avertissements qu'ils ne les ont jamais pris en compte. J'essaye d'avoir zéro avertissements à tout moment, et place des avertissements de compilateur au niveau maximum.

14

Si vous avez beaucoup d'avertissements sans importance qui ne vous importent pas, vous pouvez ignorer l'avertissement important concernant la ligne de code que vous venez d'écrire qui se cache au milieu d'eux.

+3

C'est une raison très importante de ne pas ignorer les avertissements. Probablement la raison la plus importante. –

1

Cela signifie que vous avez écrit une fonction qui prend un paramètre mais n'utilise pas le paramètre. C'est inoffensif mais cela peut indiquer des bugs dans certains cas.

Généralement, vous pouvez désactiver cet avertissement en supprimant le nom du paramètre, en le laissant anonyme, mais cela peut ne pas être souhaitable en fonction de la raison pour laquelle le paramètre n'est pas utilisé.

Je vous suggère de désactiver l'avertissement s'il est plus difficile de trouver les vrais problèmes.

+0

Pourriez-vous expliquer comment un paramètre non utilisé pourrait "... indiquer des bogues dans certains cas". ?? –

+1

int toto (int a, int b, int c) {barre de retour (a) + barre (a) + barre (c); } // oops, mcopy & paste bug, devrait appeler la barre (b) – MSalters

0

Si une méthode ne pas utiliser un paramètre alors la première question qui se pose est que pourquoi ce paramètre une partie de la signature de la méthode en premier lieu.Ces avertissements ont du sens car c'est un mauvais design auquel ils se réfèrent et en plus, il y a aussi un léger surcoût que chaque fois que cette méthode est appelée, ce paramètre est poussé sur la pile, le mieux est de refactoriser la méthode et de l'enlever ces paramètres qui n'ont aucune utilité. Cela dit, en laissant ces paramètres ne nuisent pas beaucoup, sauf pour un peu de frais que j'ai mentionné.

1

Cela dépend si vous avez l'intention d'utiliser le paramètre. Par exemple.

const int Size = 12; // intended for use in some other function 

char* MakeBuffer(int size) 
{ 
    return new char[Size]; 
} 

Dans ce code, la taille n'est pas utilisée et la constante 'Taille' est utilisée. L'avertissement mettra donc en évidence les problèmes de ce type pour vous. Toutefois, si vous n'avez jamais indenté d'utiliser le paramètre, il doit simplement être supprimé de la signature de la méthode. Sauf si vous avez besoin de faire correspondre une signature pour une méthode virtuelle ou un pointeur de fonction, si tel est le cas, vous n'avez pas la possibilité de le supprimer.

1

En C++, vous pouvez avoir des arguments par défaut:

int sum(int first, int second=0){ // should not give warning 
    return first+first; 
} 

Vous pouvez également argument supplémentaire:

int sum(int first, int second){  // should give warning 
    first *= 2; 
    return first; 
} 

Si vous avez un paramètre que vous ne l'utilisez et ce n'est pas par défaut, vous devriez recevoir un avertissement parce que vous demandez au programme de transmettre à la pile des valeurs supplémentaires qui ne sont jamais référencées, et qui font donc plus de travail que nécessaire.

Cela signifie peut-être que vous avez également oublié une partie de la logique de la fonction.

+0

Je crois que les valeurs sont toujours passées à la fonction s'il n'y a pas de paramètre formel. Il n'y a aucun nom local pour accéder à la valeur par. –

+0

Je suis confus par cet exemple - même avec l'argument par défaut, pourquoi voudriez-vous le deuxième paramètre dans cet exemple? Que vous passiez quelque chose ou non, il ne sera jamais utilisé. La seule chose que je peux penser est si vous ne l'utilisez pas maintenant, mais vous prévoyez que l'API aura besoin de l'information à l'avenir. –

14

Pour une manière spécifique gcc pour désactiver l'avertissement, vous pouvez utiliser __attribute__((unused)) comme

void foo(int a, int b __attribute__((unused))) { 

} 

Pour ignorer le second paramètre. Si votre programme s'appuie déjà sur les technologies GCC, vous pouvez utiliser cet attribut pour être sûr à 100% de ce type d'avertissement.

Questions connexes