Wieder mal eine nette Falle: Implizite Konvertierungen und ein Refactoring-Versuch.
Folgende Methoden wurden in einer Klasse verwendet:
...
bool GetTableCoreData(long lIdAddrSet,
CAgvipTableCoreData &coreData,
bool bSilent=false);
bool GetTableCoreData(long lIdAddrSet, long lIdProject,
CAgvipTableCoreData &coreData,
bool bSilent=false);
bool GetTableCoreData(long lIdAddrSet,
CDataConnection &dataConnection,
CAgvipTableCoreData &coreData);
...
Die dritte Methode passte mir nicht von der Reihenfolge der Argumente. und ich änderte sie wie folgt um:
bool GetTableCoreData(long lIdAddrSet,
CAgvipTableCoreData &coreData,
CDataConnection &dataConnection);
Ich habe mich nun einfach darauf verlassen, dass der Compiler mir alle entsprechenden Code Stellen schon anmeckern wird, an denen hier was nicht passt. Da ich noch einiges anderes an der Klasse geändert hatte, dauerte es noch eine Weile bis ich den nächsten Build angeworfen habe, und ehrlich gesagt, habe ich das Refactoring dieser Funktion vergessen.
Typischer Fall von: Zu viel auf einmal & Der Compiler macht einfach nicht was ich will 😉
Was passierte? Nichts ❗
Ich bekam keine Fehlermeldung zu dieser Änderung, denn CDataConnection hat eine implizite Konvertierung auf bool. Die Folge war, dass die erste Signatur der Funktion auch dieser Folge von Argumenten entsprach.
bool GetTableCoreData(long lIdAddrSet,
CAgvipTableCoreData &coreData,
bool bSilent=false);
Logisch, dass diese Funktion natürlich eine anderes Verhalten hatte und hier nicht mehr das passierte was ich eigentlich wollte.
Dämlicherweise rutschte diese Änderung auch noch durch die Tests und eine ganze Funktionsgruppe unserer Software wurde lahmgelegt und so ausgeliefert… Ein Bug, dazu noch von der Kategorie vermeidbar.
Was lernen wir:
- Es gibt keine fehlerfreie Software!
- Die kleinen Änderungen bringen die größten Fehler!
- Sich beim Refactoring auf den Compiler zu verlassen kann tückisch werden!