Si je tombe sur un vieux code qui n' if (!this) return;
dans une application, la gravité du risque est-ce? Est-ce une dangereuse bombe à retardement qui nécessite une application immédiate de recherche à l'échelle et de détruire l'effort, ou est-il plus comme une odeur de code qui peuvent être parti tranquillement en place?
Je ne suis pas la planification sur l'écriture de code qui fait cela, bien sûr. Plutôt, j'ai récemment découvert quelque chose dans une vieille bibliothèque de base utilisé par de nombreuses pièces de notre application.
Imaginez un CLookupThingy
classe a un non-virtuel, CThingy *CLookupThingy::Lookup( name )
de la fonction membre. Apparemment, l'un des programmeurs de retour dans les cowboy jours a rencontré de nombreux plantages où NULL CLookupThingy *
s ont été transmis à partir de fonctions, et plutôt que de fixer des centaines de sites d'appel, tranquillement, il fixe jusqu'Lookup():
CThingy *CLookupThingy::Lookup( name )
{
if (!this)
{
return NULL;
}
// else do the lookup code...
}
// now the above can be used like
CLookupThingy *GetLookup()
{
if (notReady()) return NULL;
// else etc...
}
CThingy *pFoo = GetLookup()->Lookup( "foo" ); // will set pFoo to NULL without crashing
J'ai découvert ce petit bijou plus tôt cette semaine, mais maintenant je suis en conflit quant à savoir si je devrais le réparer. C'est dans une bibliothèque de base utilisé par tous de nos applications. Plusieurs de ces applications ont déjà été livrés à des millions de clients, et il semble fonctionner correctement; il n'y a pas des accidents ou d'autres insectes à partir de ce code. Retrait de l' if !this
dans la fonction recherche signifie la fixation des milliers de sites d'appel qui, potentiellement, passer la valeur NULL; inévitablement, ne sera pas atteint, l'introduction de nouveaux bugs qui apparaîtront de façon aléatoire au cours de la prochaine année de développement.
De sorte que je suis enclin à le laisser seul, sauf si absolument nécessaire.
Étant donné qu'il est techniquement un comportement indéfini, quel est le danger d' if (!this)
dans la pratique? Est-il digne de l'homme-semaines de travail à fixer, ou peut MSVC et GCC compter sur le retour en toute sécurité?
Notre application compile sur MSVC et de GCC, et fonctionne sur Windows, Ubuntu, et MacOS. Transférabilité à d'autres plates-formes n'est pas pertinent. La fonction en question est la garantie de ne jamais être virtuel.
Edit: Le genre de réponse objective, je suis à la recherche de quelque chose comme
- "Les versions actuelles de MSVC et GCC utilisation de l'ABI où nonvirtual les membres sont vraiment statique avec un implicite de ce paramètre; c'est pourquoi ils seront en toute sécurité dans la fonction, même si" il "est NULL" ou
- "une prochaine version de GCC va changer l'ABI de sorte que même nonvirtual fonctions nécessitent le chargement d'une direction de la cible à partir du pointeur de classe" ou
- "la GCC 4.5 a une incohérence ABI où, parfois, il compile nonvirtual membres de succursales directes avec un paramètre implicite, et parfois en tant que classe-décalage des pointeurs de fonction."
L'ancien signifie que le code est puant, mais peu probable de pause; le second est quelque chose à tester après un compilateur de mise à niveau; celui-ci exige une action immédiate, même à coût élevé.
C'est clairement latente bug en attente de se produire, mais pour l'instant je me préoccupe seulement de réduire les risques sur nos compilateurs.