Évitez d’avertir “paramètre formel non référencé”

J’ai une super classe comme ça:

class Parent { public: virtual void Function(int param); }; void Parent::Function(int param) { std::cout << param << std::endl; } 

..et une sous-classe comme ceci:

 class Child : public Parent { public: void Function(int param); }; void Child::Function(int param) { ;//Do nothing } 

Lorsque je comstack le fichier de sous-classe .cpp, j’obtiens cette erreur

 warning C4100: 'param' : unreferenced formal parameter 

En pratique, nous traitions les avertissements comme des erreurs. Comment éviter l’avertissement ci-dessus?

Merci.

En C ++, vous n’avez pas à donner un paramètre que vous n’utilisez pas de nom, vous pouvez donc faire ceci:

 void Child::Function(int) { //Do nothing } 

Vous souhaiterez peut-être conserver le nom du paramètre dans la déclaration dans le fichier d’en-tête à l’aide de la documentation. L’instruction vide ( ; ) est également inutile.

Je préfère utiliser une macro, car elle indique non seulement mon intention au compilateur, mais également aux autres responsables du code, et il est possible d’effectuer des recherches plus tard.

La méthode de commenter le nom de l’argument peut facilement être manquée par les personnes qui ne connaissent pas le code (ou moi 6 mois plus tard).

Cependant, c’est un problème de style, ni l’une ni l’autre n’est “meilleure” ou plus optimale en ce qui concerne le code généré, les performances ou la robustesse. Pour moi, le facteur décisif est d’informer les autres de mon intention au moyen d’un système normalisé. Omettre le nom du paramètre et insérer un commentaire fonctionnerait tout aussi bien:

 void CFooBar::OnLvnItemchanged(NMHDR *pNMHDR, LRESULT *pResult) { UNREFERENCED_PARAMETER(pNMHDR); 

Alternativement:

 void CFooBar::OnLvnItemchanged(NMHDR* /* pNMHDR */, LRESULT *pResult) { // Not using: pNMHDR 

Je dirais que la pire solution est de supprimer le message d’avertissement; cela affectera tout votre fichier ou projet, et vous perdrez la connaissance que peut-être vous avez manqué quelque chose. Au moins, en ajoutant la macro ou en commentant le nom de l’argument, vous avez dit aux autres que vous avez pris la décision consciente de ne pas utiliser cet argument et que ce n’est pas une erreur.

Le SDK Windows dans WinNT.h définit UNREFERENCED_PARAMETER() avec DBG_UNREFERENCED_PARAMETER() et DBG_UNREFERENCED_LOCAL_VARIABLE() . Ils évaluent tous la même chose, mais la différence est que DBG_UNREFERENCED_PARAMETER () est utilisé lorsque vous démarrez et que vous prévoyez d’utiliser le paramètre lorsque le code est plus complet. Lorsque vous êtes certain de ne jamais utiliser le paramètre, utilisez la version UNREFERENCED_PARAMETER ().

Les Microsoft Foundation Classes (MFC) ont une convention similaire, avec les macros UNUSED_ALWAYS() et UNUSED_ALWAYS() plus courtes.

Choisissez un style et respectez-le. De cette façon, vous pourrez rechercher DBG_UNREFERENCED_PARAMETERDBG_UNREFERENCED_PARAMETER ” dans votre code et rechercher les instances où vous vous attendiez à utiliser un argument, mais non. En adoptant un style cohérent et en l’utilisant habituellement, vous faciliterez la tâche aux autres et à vous-même plus tard.

Une autre technique que vous pouvez utiliser si vous voulez conserver le nom du paramètre est de jeter pour annuler:

 void Child::Function(int param) { (void)param; //Do nothing } 

Comme @Charles Bailey mentionné, vous pouvez ignorer le nom du paramètre.

Toutefois, dans certains scénarios, vous avez besoin du nom du paramètre, car dans les versions de débogage, vous appelez un ASSERT() , mais sur les versions commerciales, il s’agit d’un nop . Pour ces scénarios, il y a des macros pratiques (au moins dans VC ++ :-)) UNREFERENCED_PARAMETER() , qui est défini comme ceci:

 #define UNREFERENCED_PARAMETER(x) x 

Notez que le simple cast @R Samuel Klatchko posté fonctionne également, mais je trouve personnellement plus lisible si le code est explicite qu’il s’agit d’un paramètre non référencé vs simple cast inexpliqué comme ça.

Je voudrais utiliser une macro pour supprimer l’avertissement de paramètre formel non référencé:

 #define UNUSED( x ) ( &reinterpret_cast< const int& >( x ) ) 

Cela présente les avantages suivants:

  • Contrairement à #define UNUSED (x) (void) x, il n’est pas nécessaire de voir la définition complète du type du paramètre pour qu’il n’y en ait pas eu auparavant.
  • Contrairement à #define UNUSED (x) & x, il peut être utilisé en toute sécurité avec des parameters dont les types surchargent l’unaire & l’opérateur.

Pragma fonctionne bien aussi car il est clair que vous utilisez VS. Cet avertissement a un rapport bruit sur bénéfice très élevé, étant donné que les parameters non référencés sont très courants dans les interfaces de rappel et les méthodes dérivées. Même les équipes de Microsoft Windows qui utilisent W4 en ont assez de son caractère inutile (serait plus adapté à / Wall) et ont simplement ajouté à leur projet:

 #pragma warning(disable: 4100) 

Si vous souhaitez réduire l’avertissement pour un bloc de code, entourez-le de:

 #pragma warning(push) #pragma warning(disable: 4100) void SomeCallbackOrOverride(int x, float y) { } #pragma warning(pop) 

La pratique consistant à omettre le nom du paramètre présente l’inconvénient du débogueur que vous ne pouvez pas facilement inspecter par nom ni l’append à la montre (devient confus si vous avez plus d’un paramètre non référencé), et qu’une implémentation particulière d’une méthode peut ne pas utiliser le paramètre, sachant sa valeur peut vous aider à déterminer à quel stade d’un processus vous êtes, en particulier lorsque vous n’avez pas la stack d’appels entière au-dessus de vous.