Ce code suivant (contenant un bogue vicieux) est compilé avec GCC sans aucun avertissement. Mais, bien sûr, cela ne fonctionne pas comme prévu par le développeur (moi).
#include <iostream>
struct A
{
bool b;
void set(bool b_) { this->b = b_; }
bool get() const { return this-b; } // The bug is here: '-' instead of '->'
};
int main()
{
A a;
a.set(true);
std::cout << a.get() << std::endl; // Print 1
a.set(false);
std::cout << a.get() << std::endl; // Print 1 too...
return 0;
}
Quel avertissement puis-je ajouter pour le compilateur (GCC 4.8) pour éviter ce genre de faute de frappe?
Question liée: existe-t-il une option pour forcer (ou avertir) l'accès aux variables/fonctions membres avec this->
?
Ce problème particulier est détecté par cppcheck
:
$ cppcheck --enable = all this-minus-bool.cxx Vérification de ceci-minus-bool.cxx ... [this-minus-bool.cxx: 7 ]: (avertissement) Soustraction de pointeur suspecte. Aviez-vous l'intention d'écrire '->'? (Information) Cppcheck ne trouve pas tous les fichiers d'inclusion (utilisez --check-config pour plus de détails)
C'était avec aucun chemin d'inclusion donné. Si j'ajoute -I /usr/include/c++/4.8/
, le problème est toujours détecté:
Vérification de this-minus-bool.cxx ... [This-minus-bool.cxx]: (informations) Trop de configurations #ifdef - cppcheck ne vérifie que 12 des 45 configurations. Utilisez --force pour vérifier toutes les configurations. [This-minus-bool.cxx: 7]: (avertissement) Soustraction de pointeur suspecte. Aviez-vous l'intention d'écrire '->'? [/ Usr/include/c ++/4.8/bits/ostream.tcc: 335]: (style) Struct '__ptr_guard' a un constructeur avec 1 argument qui n'est pas explicite. [/ usr/include/c ++/4.8/bits/locale_classes.tcc: 248]: (erreur) Désallocation d'un pointeur désalloué: __c
puis cppcheck travaille lentement à travers le #ifdef
configurations.
(Remarque: l'erreur dans local_classes.tcc
est un faux positif, mais c’est très difficile à dire pour un outil automatisé, car il faut savoir que le bloc catch
de ce site ne doit pas être entré lorsque la macro __EXCEPTIONS
n'est pas réglé.)
Disclaimer: Je n'ai aucune autre expérience avec cppcheck.
Non, this - b
exécute arithmétique du pointeur sur le pointeur this
, malgré que b
soit un type bool
(b
est implicitement converti en int
).
(Fait intéressant, vous pouvez toujours définir this + b
vers un pointeur où b
est un type bool
, car vous pouvez définir un pointeur après la fin d'un scalaire! Alors même votre favori comportement indéfini le suiveur le permettrait.)
La vérification des limites de tableaux a toujours été le travail d'un programmeur C++.
Notez également que dans vos cas, l'utilisation de this
est superflue: limiter ainsi cette utilisation excessive est un moyen de résoudre le problème.
Je voudrais suggérer un autre outil (en dehors de cppcheck
proposé par @ arne-vogel), donnant une meilleure aide visuelle au lieu de l'avertissement demandé:
Utilisez format-clang pour formater automatiquement votre code. Le résultat pourrait ressembler à ceci (selon les paramètres), rendant le bogue plus visible par les espaces ajoutés autour de operator-
:
struct A {
bool b;
void set(bool b_) { this->b = b_; }
bool get() const { return this - b; }
};