Disons que j'ai une condition booléenne a AND b OR c AND d
et que j'utilise un langage dans lequel l' AND
ordre de priorité des opérations est supérieur à celui de OR
. Je pourrais écrire cette ligne de code:
If (a AND b) OR (c AND d) Then ...
Mais en réalité, cela équivaut à:
If a AND b OR c AND d Then ...
Existe-t-il des arguments pour ou contre l'inclusion des parenthèses superflues? Est-ce que l'expérience pratique suggère qu'il vaut la peine de les inclure pour plus de lisibilité? Ou est-ce un signe qu'un développeur doit vraiment s'asseoir et avoir confiance en les bases de son langage?
coding-style
operator-precedence
Jeff Bridgman
la source
la source
2 * 3 + 2
pourrait être le même que,(2 * 3) + 2
mais le second est plus facile à lire.Réponses:
Les bons développeurs s'efforcent d'écrire du code clair et correct . Les parenthèses conditionnelles, même si elles ne sont pas strictement requises, aident à la fois.
En ce qui concerne la clarté , pensez aux parenthèses comme les commentaires dans le code: elles ne sont pas strictement nécessaires et, en théorie, un développeur compétent devrait pouvoir comprendre le code sans eux. Et pourtant, ces indices sont extrêmement utiles, car:
De plus, des parenthèses supplémentaires, tout comme les indentations, les espaces et autres normes de style, aident à organiser visuellement le code de manière logique.
Pour ce qui est de l' exactitude , les conditions sans parenthèses sont une recette pour des erreurs stupides. Lorsqu'ils se produisent, ils peuvent constituer des bogues difficiles à trouver, car souvent, une condition incorrecte se comporte correctement la plupart du temps et n'échoue qu'occasionnellement.
Et même si vous comprenez bien, la prochaine personne à travailler sur votre code ne peut pas, soit ajouter des erreurs à l'expression, soit mal comprendre votre logique, et donc ajouter des erreurs ailleurs (comme le fait remarquer à juste titre LarsH).
J'utilise toujours des parenthèses pour les expressions combinant
and
etor
(ainsi que pour les opérations arithmétiques présentant des problèmes de priorité similaires).la source
Peu importe que vous ayez confiance en votre compréhension de la langue. Ce qui compte le plus, c’est l’appréhension du langage du n00b qui vous suit.
Écrivez votre code de la manière la plus claire et la plus claire possible. Des parenthèses supplémentaires aident souvent (mais pas toujours). Mettre une seule déclaration sur une ligne aide souvent. La cohérence dans le style de codage aide souvent.
Trop de parenthèses existent, mais c’est l’une des situations dans lesquelles vous n’avez pas besoin de conseils - vous le saurez quand vous le verrez. À ce stade, modifiez votre code pour réduire la complexité de l'instruction plutôt que de supprimer les parenthèses.
la source
There is such a thing as too many parenthesis
- tu n'es évidemment pas liseuse;)Oui
Vous devez toujours utiliser des parenthèses ... vous ne contrôlez pas l'ordre de priorité ... le développeur du compilateur le fait. Voici une histoire qui m'est arrivée à propos de la non utilisation de parenthèses. Cela a affecté des centaines de personnes sur une période de deux semaines.
Raison du monde réel
J'ai hérité d'une application main-frame. Un jour, hors du bleu clair, il a cessé de fonctionner. C'est ça ... pouf ça vient de s'arrêter.
Mon travail consistait à le faire fonctionner aussi vite que possible. Le code source n'avait pas été modifié depuis deux ans, mais tout à coup, il s'est arrêté. J'ai essayé de compiler le code et il s'est cassé sur la ligne XX. J'ai regardé la ligne XX et je ne pouvais pas dire ce qui ferait la rupture de la ligne XX. J'ai demandé les spécifications détaillées pour cette application et il n'y en avait pas. La ligne XX n'était pas le coupable.
J'ai imprimé le code et commencé à l'examiner de haut en bas. J'ai commencé à créer un organigramme de ce qui se passait. Le code était si compliqué que je ne pouvais même pas en comprendre le sens. J'ai arrêté d'essayer de l'organigramme. J'avais peur de faire des changements sans savoir comment ce changement affecterait le reste du processus, d'autant plus que je n'avais aucun détail sur le fonctionnement de l'application ni sur son emplacement dans la chaîne de dépendance.
J'ai donc décidé de commencer en haut du code source et d'ajouter des freins à ligne et à ligne pour rendre le code plus lisible. J'ai remarqué que, dans certains cas, certaines conditions étaient réunies
AND
etOR
qu'il n'était pas clairement possible de distinguer entre les donnéesAND
éditées et les donnéesOR
éditées. J'ai donc commencé à mettre des parenthèses sur les conditionsAND
etOR
pour les rendre plus lisibles.Alors que je descendais lentement pour le nettoyer, je sauvegardais périodiquement mon travail. A un moment, j'ai essayé de compiler le code et une chose étrange s'est produite. L'erreur avait dépassé la ligne de code d'origine et était maintenant plus basse. Alors j'ai continué, speparating le
AND
etOR
conditions avec parens. Quand j'ai fini de le nettoyer, ça a fonctionné. Allez comprendre.J'ai ensuite décidé de visiter l'atelier des opérations et de leur demander s'ils avaient récemment installé de nouveaux composants sur le châssis principal. Ils ont dit oui, nous avons récemment mis à jour le compilateur. Hmmmm.
Il s'est avéré que l'ancien compilateur évaluait l'expression de gauche à droite malgré tout. La nouvelle version du compilateur a également évalué les expressions de gauche à droite, mais un code ambigu, ce qui signifie une combinaison peu claire de
AND
etOR
ne peut pas être résolu.La leçon que j'ai apprise de cela ... TOUJOURS, TOUJOURS, TOUJOURS utiliser des parens dans des
AND
conditions distinctes et desOR
conditions lorsqu'ils sont utilisés conjointement.Exemple simplifié
IF Product = 191 OR Product = 193 AND Model = "ABC" OR Product = 201 OR Product = 202 AND Model = "DEF" ...
(Code jonché de plusieurs d'entre eux)Ceci est une version simplifiée de ce que j'ai rencontré. Il y avait aussi d'autres conditions avec des énoncés de logique booléenne composés.
Je me souviens de l'avoir malmené pour:
IF ((Product = 191 OR Product = 193) AND Model = "ABC") OR ((Product = 201 OR Product = 202) AND Model = "DEF") ...
Je ne pouvais pas le réécrire car il n'y avait pas de spécifications. L'auteur original était parti depuis longtemps. Je me souviens d'une pression intense. Un cargo tout entier était bloqué dans le port et ne pouvait être déchargé car ce petit programme ne fonctionnait pas. Pas d'avertissement. Aucune modification du code source. Il m'est simplement apparu de demander aux Opérations du réseau si elles modifiaient quoi que ce soit après avoir remarqué que l'ajout de parenthèses avait modifié les erreurs.
la source
Oui, s'il y a un mélange de 'et' et 'ou'.
Aussi bonne idée de () ce qui est logiquement une vérification.
Bien que le mieux est d’utiliser des fonctions de prédicat bien nommées et d’évacuer la plupart des vérifications et conditions présentes, en laissant les choses simples et lisibles.
la source
a AND b
deviez probablement être remplacé par une fonction ou une valeur boolen pré-calculée ayant un nom plus descriptif.Les parenthèses sont sémantiquement redondantes, donc le compilateur s'en fiche, mais c'est un fil rouge - la vraie préoccupation est la lisibilité et la compréhension du programmeur.
Je vais prendre la position radicale ici et donner un copieux « non » aux parenthèses dans
a AND b OR c AND d
. Chaque programmeur doit savoir par cœur que la priorité dans les expressions booléennes ne va PAS> ET> OU , comme si vous vous souveniez Veuillez excuser ma chère tante Sally pour les expressions algébriques. La ponctuation redondante ajoute simplement un fouillis visuel dans le code sans aucun avantage pour la lisibilité du programmeur.En outre, si vous utilisez toujours des parenthèses dans les expressions logiques et algébriques, vous ne pouvez plus les utiliser comme marqueur de "quelque chose de délicat se passe ici - faites attention!" C'est-à-dire que dans les cas où vous souhaitez remplacer la priorité par défaut et faire évaluer l'addition avant la multiplication, ou OU avant, les parenthèses constituent un joli drapeau rouge pour le prochain programmeur. Trop d'utilisation d'eux quand ils ne sont pas nécessaires, et vous devenez le garçon qui a pleuré Wolf.
Je ferais une exception pour tout ce qui ne relève pas du domaine de l'algèbre (qu'il soit booléen ou non), tel que les expressions de pointeur en C, où tout ce qui est plus compliqué que des idiomes standard tels que
*p++
oup = p->next
devraient probablement être mis entre parenthèses pour que le déréférencement et l'arithmétique soient droits. Et, bien sûr, rien de tout cela ne s'applique aux langues telles que Lisp, Forth ou Smalltalk qui utilisent une forme de notation polonaise pour les expressions; mais pour la majorité des langues traditionnelles, la priorité logique et arithmétique est totalement normalisée.la source
AND
vsOR
est un cas relativement simple que je voudrais faire connaître aux autres développeurs de mon équipe. Je crains que parfois "utiliser des parenthèses pour plus de clarté", c’est vraiment "utiliser des parenthèses, de sorte que je n’ai jamais à prendre la peine d’apprendre la priorité"..member
avant les opérateurs unaires, avant unaire opérateurs binaires,*
et/
avant+
et-
avant<
et>
et==
avant&&
avant||
avant l' affectation. Ces règles sont faciles à retenir car elles correspondent à mon "bon sens" concernant la manière dont les opérateurs sont normalement utilisés (par exemple, vous ne donneriez pas==
plus de priorité à+
ou1 + 1 == 2
cesser de fonctionner) et couvrent 95% des questions de liste de priorité que j'aurais. .Comme je le vois:
OUI les avantages:
Oui les inconvénients:
AUCUN avantage:
NON Inconvénients:
la source
3 * a^2 + 2 * b^2
plus facile à lire que(3 * (a^2)) + (2 * (b^2))
parce que le format et la priorité sont familiers et standard. De même, vous pourriez (pour être extrême) interdire l'utilisation de fonctions et de macros (ou de compilateurs!) Afin de rendre la sémantique de votre code plus explicite. Évidemment, je ne le préconise pas, mais j'espère pouvoir répondre à votre question sur les raisons pour lesquelles il faut imposer des limites (un équilibre) pour rendre les choses explicites.Si personne d'autre n'avait à revoir mon code, je ne pense pas que je m'en soucierais.
Mais, d'après mon expérience:
Je le fais presque toujours parce que je me fie à ma capacité de lire rapidement et de ne pas faire de petites erreurs beaucoup plus avec des pairs que rien d’autre.
Dans votre cas, je ferais presque assurément quelque chose comme:
Oui, c'est plus de code. Oui, je peux faire à la place des opérateurs fantaisistes. Non, je n'aime pas trop le risque que j'écrive le code d'un an ou plus dans le futur. J'ai mal interprété les opérateurs fantaisistes. Que se passe-t-il si j'écrivais du code dans une langue qui avait une priorité différente ET / OU et que je devais revenir en arrière pour résoudre ce problème? Est-ce que je vais y aller, "aha! Je me souviens de cette petite chose intelligente que j'ai faite! Je n'avais pas à inclure les parens quand j'ai écrit cette année, bonne chose que je me souvienne maintenant!" si cela se produit (ou pire, quelqu'un d'autre qui n'était pas au courant de cette intelligence ou qui a été jeté dans une situation de type "solution immédiate")?
Séparer avec () rend beaucoup plus facile de parcourir rapidement et de comprendre plus tard ...
la source
ab = a AND b
?ab
que restera inchangé sinona AND b
.Cas général
En C #, la multiplication et la division ont la priorité sur l'addition et la soustraction.
Pourtant, StyleCop, un outil qui applique un style commun à l’ensemble de la base de code avec un objectif supplémentaire, à savoir la règle SA1407, consiste à atténuer le risque que des bogues ne soient introduits par code . Cette règle produira un avertissement avec un morceau de code comme ceci:
Il est clair que le résultat est
7
et non9
, mais néanmoins, StyleCop suggère de mettre des parenthèses:Votre cas particulier
Dans votre cas particulier, il existe une priorité de AND par rapport à OR dans la langue que vous utilisez.
Ce n'est pas comme ça que chaque langue se comporte. Beaucoup d'autres traitent ET et OU de manière égale.
En tant que développeur travaillant principalement avec C #, lorsque j'ai vu votre question pour la première fois et lu le code sans lire ce que vous aviez écrit auparavant, ma première tentation a été de dire que les deux expressions ne sont pas identiques. J'espère que j'ai lu toute la question avant de commenter.
Cette particularité et le risque que certains développeurs pensent que ET et OU ont la même priorité rend encore plus important l’ajout de parenthèses.
N'écrivez pas de code dans le but de montrer que vous êtes intelligent. Écrivez un code avec un objectif de lisibilité, y compris par des personnes qui ne sont peut-être pas familiarisées avec tous les aspects de la langue.
la source
Comme tout le monde l'a dit, utilisez des parenthèses à chaque fois, cela rend l'expression plus lisible. Cependant, si l'expression est compliquée, je conseillerais d' introduire de nouvelles fonctions pour les sous-expressions .
la source
Si vous utilisez strictement la langue au singulier, peut-être. Maintenant, prenez tous les langages que vous connaissez, des âges aux plus modernes, de la compilation au scripting en passant par le SQL et votre propre DSL que vous avez inventé le mois dernier.
Vous souvenez-vous des règles de priorité exactes pour chacune de ces langues, sans regarder?
la source
"Dois-je utiliser des parenthèses dans les instructions logiques même si cela n’est pas nécessaire?"
Oui, parce que deux personnes les trouveront utiles:
Le prochain programmeur, dont les connaissances, les compétences ou le style peuvent être différents
L'avenir vous qui revenez à ce code à une date ultérieure!
la source
Les conditionnelles complexes sont "l'algèbre de Boolean", ce que vous écrivez d'une manière qui donne l'impression qu'elle ressemble beaucoup à l'algèbre, et que vous utiliseriez certainement des parens pour l' algèbre , n'est-ce pas?
Les règles vraiment utiles sont celles de la négation:
Ou, dans un format un peu plus clair:
ce qui est vraiment clairement juste algèbre quand écrit comme:
Mais nous pouvons également appliquer la réflexion à la simplification algébrique et à l’extension:
bien que dans le code vous devez écrire:
ou, dans un format un peu plus clair:
Fondamentalement, une condition est toujours juste une expression algébrique, et en utilisant clairement une parenthèse, vous pouvez plus facilement appliquer les différentes règles algébriques que vous connaissez déjà à l'expression, y compris votre ancien concept de "simplifier ou élargir cette formule".
la source
!(A + B) <=> !A + !B
et-1*(A + B) = -A + -B
ne doit pas l'opérateur a été renversé de+
à*
la deuxième expression?Je vais utiliser des parenthèses même si cela est facultatif, car cela aide à mieux comprendre pour tout le monde, pour celui qui écrit le code ainsi que pour celui qui est prêt à le voir. Dans votre cas, même les opérateurs booléens ont la priorité, cela pourrait bien fonctionner au début, mais nous ne pouvons pas dire que cela vous aidera dans tous les cas. Je préfère donc utiliser la parenthèse utilisateur dans toutes les conditions qui peuvent l'exiger ou éventuellement.
la source
Oui. Vous devez utiliser dans tous les cas lorsque vous sentez que votre code sera plus clair. N'oubliez pas que votre code doit être suffisamment clair pour que les autres puissent comprendre sans lire vos commentaires dans le code. C'est donc une bonne pratique d'utiliser des parenthèses et des accolades. Gardez également à l'esprit que cela peut dépendre de la pratique particulière de votre entreprise / équipe. Il suffit de maintenir une approche et de ne pas mélanger.
la source