Un premier cas géré est celui où quelque chose qui n’est pas un signal est pourtant connecté comme s’il en était un. Cependant, sans Clazy, un code comme celui-ci compilerait sans problème, puisqu’il n’y a pas d’erreur de syntaxe C++ — juste une erreur de sémantique Qt.
Code : | Sélectionner tout |
1 2 | // warning: MyObj::mySlot is not a signal [-Wclazy-connect-non-signal] connect(obj, &MyObj::mySlot, &MyObj::mySlot2); |
Code : | Sélectionner tout |
1 2 3 4 5 6 | void myFunction() { int localVar = ...; // program will crash when signal is emitted! connect(m_object, &MyObj::mySignal, [&localVar] { ... }); } |
Code : | Sélectionner tout |
1 2 3 4 5 | connect(m_widget, &MyWidget::textChanged, [this] (const QString &text) { m_receiver->update(text, false); }); connect(m_widget, &MyWidget::textChanged, m_receiver, [this] (const QString &text) { (....) }); |
Ajouter des slots dans une classe qui hérite de QThread n’est pas forcément un problème en soi, mais est souvent un signe de code mal conçu : en effet, ces slots sont exécutés dans le fil d’exécution correspondant à l’objet QThread, mais pas dans le fil QThread. Il vaut souvent mieux utiliser des objets travailleurs.
Toute utilisation de l’ancienne syntaxe avec SIGNAL() et SLOT() est aussi signalée : en effet, elle ne permet pas au compilateur d’effectuer beaucoup de vérifications, contrairement à celle utilisant des pointeurs vers des fonctions membres.
Si certains types ne sont pas normalisés avec les macros SIGNAL(), SLOT(), Q_ARG() ou Q_RETURN_ARG(), quelques allocations de mémoire inutiles sont effectuées.
Code : | Sélectionner tout |
1 2 3 | // warning: Signature is not normalized. Use void mySlot(int) instead of void mySlot(const int) [-Wclazy-connect-not-normalized] o.connect(&o, SIGNAL(mySignal(int, int)), &o, SLOT(void mySlot(const int))); |
Souvent, un slot n’est pas une méthode constante (comme pourrait l’être un accesseur). Un signal n’a pas besoin d’être marqué comme constant. Ces cas arrivent cependant fréquemment lors d’une interaction avec du code QML, mais il vaut mieux utiliser Q_PROPERTY ou Q_INVOKABLE qu’un slot.
Pour des raisons de lisibilité, les signaux devraient toujours être émis avec le mot clé emit (ou la macro Q_EMIT), non comme de simples méthodes. De même, ces mot clé et macro ne devraient être utilisés qu’avec des signaux.
Les connexions par nom sont une vieille fonctionnalité, qui n’a jamais été très populaire et ne devrait plus être utilisée. De fait, simplement renommer un objet pourrait casser des connexions — ces constructions sont donc extrêmement fragiles. La nouvelle syntaxe de connexion rend les choses explicites à la compilation.
Les propriétés Q_PROPERTY non constantes devraient toujours avoir une méthode NOTIFY, pour prévenir de tout changement de valeur. Bien que les utilisations de ces méthodes ne se soient réellement popularisées que depuis QML, n’importe qui pourrait en avoir besoin — GammaRay, par exemple.
Source : Nailing 13 signal and slot mistakes with clazy 1.3.