web-dev-qa-db-fra.com

Existe-t-il une option GCC pour prévenir de l’écriture de `this-field` au lieu de` this-> field`?

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->?

62
Caduchon

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.

71
Arne Vogel

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.

32
Bathsheba

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; }
};
13
Simon