Ma question porte sur la ligne que j'ai mentionnée dans le sujet et que je peux voir à de nombreux endroits dans le code de production.
Le code global ressemble à ceci:
if (0) {
// Empty braces
} else if (some_fn_call()) {
// actual code
} else if (some_other_fn_call()) {
// another actual code
...
} else {
// default case
}
Les autres branches ne sont pas pertinentes pour ma question. Je me demande quel est le sens de mettre if (0)
ici. Les accolades sont vides, donc je ne pense pas qu'il soit censé commenter un bloc de code. Est-ce que cela force le compilateur à faire une optimisation ou ses intentions sont-elles différentes?
J'ai essayé de rechercher ce cas explicite ici sur SO et sur Internet, mais sans succès. Il y a des questions similaires sur JavaScript, mais pas C. Il y a une autre question, que se passe-t-il quand un zéro est attribué dans une condition `if`? , mais il traite de l'affectation de zéro à une variable, pas de l'utilisation de «if (0)» elle-même.
la source
Réponses:
J'utilise parfois ceci pour la symétrie afin que je puisse déplacer l'autre
else if{
librement avec mon éditeur sans avoir à me soucier du premierif
.Sémantiquement le
part ne fait rien et vous pouvez compter sur les optimiseurs pour le supprimer.
la source
if else
préfixe commun à tous les chemins de code significatifs aligne bien les conditions et facilite leur analyse. (C'est subjectif, cependant, et dépendrait beaucoup de ce qui est vraiment à l'intérieur des conditions et des blocs de code.)if (0) {..}
ait de problème de parsabilité / lisibilité. Cela devrait être évident pour quiconque connaît un peu C. Ce n'est pas un problème. Le problème est la question de suivi après l'avoir lu: "Pourquoi diable est-ce alors?" À moins que ce ne soit à des fins de débogage / temporaires (c'est-à-dire que l'intention est «d'activer» ceif
bloc plus tard), je recommanderais la suppression complète. Fondamentalement, "lire" un tel code provoquerait probablement une "pause" inutile pour le lecteur sans raison valable. Et c'est une raison suffisante pour le supprimer.else if
dans l'éditeur sans souci" car les conditions peuvent ne pas être mutuellement exclusives, auquel cas l' ordre est important. Personnellement, je n'utiliseraisif
et effectuerais un retour anticipé , en extrayant la chaîne logique vers une fonction distincte si nécessaire.Cela peut être utile s'il y a des
#if
déclarations, alaetc.
Dans ce cas, tous les tests (et tous) peuvent être
#if
supprimés et le code se compilera correctement. Presque tous les compilateurs supprimeront laif (0) {}
pièce. Un simple générateur automatique pourrait générer un code comme celui-ci, car il est légèrement plus facile à coder - il n'a pas à considérer le premier bloc activé séparément.la source
if
/else if
n'est pas tant utilisée comme un arbre de décision, mais plutôt comme une construction «agir sur la première condition de correspondance», où la condition qui se trouve avoir la priorité la plus élevée n'est pas particulièrement «spéciale». Même si je n'avais pas vuif(0)
utilisé comme un moyen de permettre à toutes les branches réelles d'avoir une syntaxe cohérente, j'aime la syntaxe cohérente qu'elle facilite.else if
ligne en deux et de mettre la garde du préprocesseur entre les deux.if (0)
branche et reformaterais le reste de manière à ce qu'ilelse
soit sur sa propre ligne, entouré d'un garde dans le sens de#if TEST1_ENABLED && TEST2_ENABLED
.J'ai vu un modèle similaire utilisé dans le code généré. Par exemple, en SQL, j'ai vu des bibliothèques émettre la
where
clause suivante .Cela rend vraisemblablement plus facile d'ajouter simplement d'autres critères, car tous les critères supplémentaires peuvent être ajoutés au début au
and
lieu d'une vérification supplémentaire pour voir s'il s'agit du premier critère ou non.la source
1=1
est également "utile" car vous pouvez toujours ajouter lewhere
devant, sans condition. Sinon, vous devrez vérifier s'il est vide, et si c'est le cas, éviter de générer lawhere
clause.1=1
deWHERE
, donc cela n'a pas d'impact sur les performances.Telle qu'elle est écrite, la
if (0) {}
clause ne se compile à rien.Je soupçonne que la fonction de la clause en haut de cette échelle est de fournir un endroit facile pour désactiver temporairement toutes les autres fonctionnalités à la fois (à des fins de débogage ou de comparaison) en remplaçant le
0
par un1
outrue
.la source
Je ne suis pas sûr des optimisations, mais mes deux cents:
Cela s'est produit à cause d'une modification du code, où une condition principale a été supprimée (l'appel de fonction dans le
if
bloc initial , disons), mais les développeurs / mainteneursif-else
blocdonc au lieu de supprimer le
if
bloc associé , ils ont simplement changé la conditionif(0)
et sont passés à autre chose.la source
if(0)
diminution de la couverture des succursales n'est-elle pas aussi?C'est la pourriture du code.
À un moment donné, «si» faisait quelque chose d'utile, la situation a changé, peut-être que la variable évaluée a été supprimée.
La personne qui réparait / changeait le système a fait le moins possible pour affecter la logique du système donc il s'est simplement assuré que le code serait recompilé. Alors il laisse un "si (0)" parce que c'est rapide et facile et il n'est pas totalement sûr que ce soit ce qu'il veut faire. Il fait fonctionner le système et il ne revient pas en arrière pour le réparer complètement.
Ensuite, le développeur suivant arrive et pense que cela a été fait délibérément et ne commente que cette partie du code (car elle n'est de toute façon pas évaluée), puis la prochaine fois que le code est touché, ces commentaires sont supprimés.
la source
Une possibilité non encore mentionnée: la
if (0) {
ligne pourrait fournir un emplacement pratique pour un point d'arrêt.Le débogage est souvent effectué sur du code non optimisé, de sorte que le test toujours faux sera présent et pourra avoir un point d'arrêt défini. Une fois compilée pour la production, la ligne de code serait optimisée. La ligne apparemment inutile donne des fonctionnalités pour le développement et le test des versions sans impact sur les versions de version.
Il y a aussi d'autres bonnes suggestions ci-dessus; la seule façon de vraiment savoir quel est le but est de retrouver l'auteur et de demander. Votre système de contrôle de code source pourrait vous aider. (Recherchez la
blame
fonctionnalité -type.)la source
J'ai vu des blocs de code non accessibles dans JavaScript pré-développé qui ont été générés à l'aide d'un langage de modélisation.
Par exemple, le code que vous lisez pourrait avoir été collé à partir d'un serveur qui a pré-évalué la première condition qui, à ce moment-là, reposait sur une variable disponible uniquement côté serveur.
qui une fois pré-compilé hences:
J'espère que cela vous aidera à relativiser la faible activité potentielle du clavier de l'ère des codeurs pro-recyclage pour laquelle je manifeste de l'enthousiasme!
la source
Cette construction peut également être utilisée en C pour implémenter la programmation générique avec la sécurité de type, en s'appuyant sur le fait que le code inaccessible est toujours vérifié par le compilateur:
la source
Je pense que c'est juste un mauvais code. En écrivant un exemple rapide dans Compiler Explorer, nous voyons que dans gcc et clang aucun code n'est généré pour le
if (0)
bloc, même avec les optimisations complètement désactivées:https://godbolt.org/z/PETIks
Jouer avec la suppression des
if (0)
causes ne modifie pas le code généré, je conclus donc que ce n'est pas une optimisation.Il est possible qu'il y ait eu quelque chose dans le
if
bloc supérieur qui a ensuite été supprimé. En bref, il semble que sa suppression entraînerait la génération du même code, alors n'hésitez pas à le faire.la source
Comme cela a été dit, le zéro est évalué à faux et la branche sera probablement optimisée par le compilateur.
J'ai également vu cela auparavant dans le code où une nouvelle fonctionnalité a été ajoutée et un kill-switch était nécessaire (si quelque chose ne va pas avec la fonctionnalité, vous pouvez simplement la désactiver), et quelque temps plus tard, lorsque le kill-switch a été supprimé le le programmeur n'a pas également supprimé la branche, par exemple
est devenu
la source
Cela aide à déboguer ce bloc en mettant simplement le bloc if 1. Cela désactive la fonctionnalité de blocage de tous les if else. Et nous pouvons également étendre le bloc if else.
la source
la source
La réponse de @ PSkocik est très bien, mais j'ajoute mes deux cents. Je ne sais pas si je devrais le faire en commentaire ou en réponse; choisir ce dernier, car IMHO vaut la peine d'être vu, alors que les commentaires sont souvent invisibles.
Non seulement j'utilise occasionnellement
Mais je fais aussi parfois
ou
pour des conditions compliquées. Pour les mêmes raisons - plus facile à modifier, #ifdef, etc.
D'ailleurs, en Perl, je ferai
Je compare le
if(0)
code à lispqui, vous l'avez deviné, je peux indenter comme
J'ai parfois essayé d'imaginer à quoi pourrait ressembler une syntaxe plus lisible par l'homme.
Peut-être
inspiré du [ https://en.wikipedia.org/wiki/Guarded_Command_Language#Selection:_if[Guarded Command Language] de Dikstra ).
Mais cette syntaxe implique que les conditions sont évaluées en parallèle, alors qu'elle
if...else-if
implique une évaluation séquentielle et hiérarchisée des conditions.J'ai commencé à faire ce genre de choses en écrivant des programmes qui généraient d'autres programmes, là où c'est particulièrement pratique.
Pendant que nous y sommes, lors de l'écriture de RTL en utilisant l'ancien iHDL d'Intel, j'ai codé des trucs comme
où
FORC..DOC..ENDC
est une construction de boucle de préprocesseur de macro, qui se développe enIl s'agissait d'un code à affectation unique, non impératif, donc la définition d'une variable d'état n'était pas autorisée si vous deviez faire des choses comme trouver le premier bit défini.
À bien y penser, c'est peut-être le premier endroit où j'ai rencontré de telles constructions.
BTW, les objections que certains avaient au style if (0) - que les conditions else-if sont séquentiellement dépendantes et ne peuvent pas être arbitrairement réordonnées - ne s'appliquent pas aux logiques AND et OR et XOR dans RTL - mais s'appliquent à short- circuit && et ||.
la source
J'ai vu cela utilisé pour gérer les erreurs, par exemple
Cela peut être utile lorsque goto est utilisé pour gérer les erreurs, les instructions ne sont exécutées que lorsqu'une erreur se produit. J'ai vu cela dans un très vieux code C (où les arguments de fonction sont écrits en dehors du '()'), ne pensez pas que quiconque le suive maintenant.
la source
J'ai vu cela plusieurs fois, je pense que la raison la plus probable est qu'il évaluait quelque chose dans une version / branche ancienne / différente du code, ou peut-être pour le débogage, et le changer en
if(0)
est un moyen un peu paresseux de supprimer tout ce qui était là .la source