Est-ce une mauvaise pratique d'utiliser une instruction if sans accolades? [fermé]

130

J'ai vu du code comme celui-ci:

if(statement)
    do this;
else
    do this;

Cependant, je pense que c'est plus lisible:

if(statement){
    do this;
}else{
    do this;
}

Puisque les deux méthodes fonctionnent, est-ce simplement une question de préférence à utiliser ou est-ce qu'une méthode serait recommandée par rapport à l'autre?

jerebear
la source
À mon avis, c'est mauvais, car vous commencez à vous fier à l'indentation d'espaces blancs qui n'est presque jamais totalement cohérente. Cela fait dérailler le cours de la pensée du lecteur lorsqu'il doit s'inquiéter de telles choses.
Sridhar Sarnobat

Réponses:

212

Le problème avec la première version est que si vous revenez en arrière et ajoutez une deuxième instruction aux clauses if ou else sans vous rappeler d'ajouter les accolades, votre code se cassera de manière inattendue et amusante.

En termes de maintenabilité, il est toujours plus intelligent d'utiliser le deuxième formulaire.

EDIT: Ned le souligne dans les commentaires, mais cela vaut la peine d'être lié ici aussi, je pense. Ce ne sont pas seulement des conneries hypothétiques de la tour d'ivoire: https://www.imperialviolet.org/2014/02/22/applebug.html

clee
la source
17
Et vous devez toujours coder pour la maintenabilité. Après tout, je suis presque sûr que le compilateur ne se soucie pas de la forme que vous utilisez. Vos collègues, cependant, peuvent être pistés si vous introduisez un bug à cause d'une erreur d'accolade ridicule.
Esteban Araya
12
Ou vous pouvez utiliser un langage qui n'utilise pas de crochets pour les blocs de code ...
Tor Valamo
10
@ lins314159 - Non, je veux dire comme python. Parce que je suis chauvin à cet égard.
Tor Valamo
17
D'autres erreurs de preuve peuvent (et se produisent) se produire: imperialviolet.org/2014/02/22/applebug.html
Ned
8
Prétendre que le bogue SSL est un argument en faveur des accolades n'est pas sincère. Ce n'est pas comme si le développeur avait l'intention d'écrire if (…) { goto L; goto L; }mais avait oublié les accolades. C'est purement par hasard que `` si (…) {goto L; goto L; } `n'est pas un bogue de sécurité, car c'est toujours un bogue (mais pas un bogue avec des conséquences sur la sécurité). Sur un autre exemple, les choses pourraient aller dans la direction opposée et le code sans bretelles pourrait être accidentellement sûr. Sur un troisième exemple, le code sans accolades serait initialement sans bogue et le développeur introduirait une faute de frappe lors de l'ajout des accolades.
Pascal Cuoq
112

Un problème avec l'omission de blocs d'instructions est l'ambiguïté else. C'est-à-dire que les langages inspirés du C ignorent l'indentation et n'ont donc aucun moyen de séparer ceci:

if(one)
    if(two)
        foo();
    else
        bar();

De ceci:

if(one)
    if(two)
        foo();
else
    bar();
Doynax
la source
8
C'est un problème beaucoup plus sérieux que celui mentionné dans la réponse du haut (en ajoutant une deuxième déclaration).
3
en fait, cette réponse m'a en fait amené de la lecture cynique de ces réponses à être légèrement inquiète d'avoir fait cette erreur.
omikes
2
Si quelqu'un d'autre se demandait comme moi de quelle manière C l'interprète réellement, un test que j'ai fait avec GCC interprète ce code de la première manière. tpcg.io/NIYeqx
horta
2
«ambiguïté» n'est pas le bon terme. Il n'y a aucune ambiguïté dans la façon dont l'analyseur verra cela: le elsese lie avidement au plus proche, au plus profond if. Le problème survient lorsque le C ou des langages similaires sont codés par des personnes qui ne le savent pas, n'y pensent pas ou n'ont pas encore assez de café - alors ils écrivent du code qui, selon eux, fera une chose, mais le La spécification du langage indique que l'analyseur doit faire autre chose, ce qui peut être très différent. Et oui, c'est un autre argument solide en faveur de toujours inclure les accolades même si la grammaire les signale comme théoriquement «inutiles».
underscore_d
35

Mon schéma général est que s'il tient sur une seule ligne, je ferai:

if(true) do_something();

S'il y a une clause else, ou si le code sur lequel je veux exécuter trueest de longueur significative, accolades complètement:

if(true) {
    do_something_and_pass_arguments_to_it(argument1, argument2, argument3);
}

if(false) {
    do_something();
} else {
    do_something_else();
}

En fin de compte, cela revient à une question subjective de style et de lisibilité. Le monde de la programmation générale, cependant, se divise à peu près en deux parties (pour les langages qui utilisent des accolades): soit les utiliser tout le temps sans exception, soit les utiliser tout le temps avec exception. Je fais partie de ce dernier groupe.

Matchu
la source
4
Bien que, aussi simple que cela soit à écrire if(true){ do_something(); }, pourquoi prendre la chance de demander à un autre programmeur d'introduire un bogue sérieux sur la route (chercher le code ssl total "goto fail" d'Apple).
Craig
9
Aucune quantité de parenthèses ne permettra au mainteneur d'utiliser son cerveau. Je soutiens l'idée de "pas de parenthèses si ça tient dans une ligne" parce que, eh bien, pour moi, un tel if est juste une version de l' opérateur si ternaire où l'on n'a pas besoin de faire quoi que ce soit dans la partie "après:" de ternaire. Et pourquoi quelqu'un introduirait-il les parenthèses au ternaire si ?
Michal M
Je ne suis pas du tout d'accord pour dire qu'en fin de compte, c'est subjectif, ni que cela n'affecte que le style et la lisibilité. En tant que personne qui a perdu du temps à essayer de déboguer les problèmes qui se sont avérés être causés par des délimiteurs de bloc manquants (et ne remarquant pas leur absence), parce que j'ai dû utiliser un style de codage qui les omet lorsqu'ils sont `` inutiles '' - et qui a lu de nombreux terribles bugs très probablement causés par de tels styles de codage - je pense que c'est une question très objective et pratique. Bien sûr, avec un style imposant des délimiteurs, nous pouvons toujours les oublier, mais sûrement - au moins - la mémoire musculaire nous rend beaucoup moins susceptibles de le faire.
underscore_d
10

J'utilise le formateur de code de l'IDE que j'utilise. Cela peut différer, mais cela peut être configuré dans les Préférences / Options.

J'aime celui la:

if (statement)
{
    // comment to denote in words the case
    do this;
    // keep this block simple, if more than 10-15 lines needed, I add a function for it
}
else
{
    do this;
}
Pentium10
la source
5
Ceci étant un problème de style entièrement subjectif, je n'aime personnellement pas la redondance des lignes d'accolades uniquement. Mais salut.
Matchu
14
Je soutiens ce style. La plupart des gens lisent le code de gauche à droite et cela rend nos yeux ancrés au bord gauche de l'écran. Il permet de séparer visuellement et d'extraire le code en blocs logiques d'étapes.
mloskot
6
J'ai toujours préféré ce style. Beaucoup plus facile de trouver la parenthèse fermante correspondante. Cela prend donc beaucoup de place? Utilisez une police plus petite.
timday
4
Je trouve toujours plus facile de "scanner" le code lorsque les accolades sont sur des lignes séparées. Cela vaut pour tout; classes, méthodes, instructions if et while, et cetera. Je n'ai jamais aimé avoir ce premier appareil dentaire sur la même ligne ...
Svish
2
Les espaces blancs sont bon marché, en particulier lorsque vous avez un IDE capable de plier le code.
Moo
10

La "règle" que je suis est la suivante:

Si l'instruction "if" teste pour faire quelque chose (fonctions d'appel IE, configuration de variables, etc.), utilisez des accolades.

if($test)
{
    doSomething();
}

En effet, j'estime que vous devez préciser quelles fonctions sont appelées et où va le flux du programme, dans quelles conditions. Il est important que le programmeur comprenne exactement quelles fonctions sont appelées et quelles variables sont définies dans cette condition pour les aider à comprendre exactement ce que fait votre programme.

Si l'instruction "if" teste pour arrêter de faire quelque chose (contrôle de flux IE dans une boucle ou une fonction), utilisez une seule ligne.

if($test) continue;
if($test) break;
if($test) return;

Dans ce cas, ce qui est important pour le programmeur est de découvrir rapidement quels sont les cas exceptionnels où vous ne voulez pas que le code s'exécute, et tout cela est couvert dans $ test, pas dans le bloc d'exécution.

Marcus Harrison
la source
8

Avoir les accolades dès le premier instant devrait vous éviter d'avoir à déboguer ceci:

if (statement)
     do this;
else
     do this;
     do that;
Matt Bishop
la source
1
Cela semble être la justification acceptée, mais (pour jouer l'avocat du diable ici) une seule règle supplémentaire de mise en évidence de la syntaxe ne résoudrait-elle pas également cela, tout en économisant une ligne?
Ken
2
Il en sera de même d'avoir un IDE qui corrige l'indentation lorsque vous frappez ;:)
Sam Harwell
6

Utilisez des accolades pour toutes les instructions if, même les plus simples. Ou, réécrivez une instruction if simple pour utiliser l'opérateur ternaire:

if (someFlag) {
 someVar= 'someVal1';
} else {
 someVar= 'someVal2';
}

Cela ressemble beaucoup plus à ceci:

someVar= someFlag ? 'someVal1' : 'someVal2';

Mais n'utilisez l'opérateur ternaire que si vous êtes absolument sûr qu'il n'y a rien d'autre à faire dans les blocs if / else!

leepowers
la source
2

D'après mon expérience, le seul (très) léger avantage de la première forme est la lisibilité du code, la seconde forme ajoute du «bruit».

Mais avec les IDE modernes et la génération automatique de code (ou l'auto-complétion), je recommande fortement d'utiliser le deuxième formulaire, vous ne passerez pas plus de temps à taper des accolades et vous éviterez certains des bogues les plus fréquents.

Il y a suffisamment de bogues énergivores, les gens ne devraient tout simplement pas ouvrir les portes pour de grandes pertes de temps.

L'une des règles les plus importantes à retenir lors de l'écriture de code est la cohérence. Chaque ligne de code doit être écrite de la même manière, peu importe qui l'a écrite. Être rigoureux empêche les bugs de "se produire";)

Il en va de même pour nommer clairement et explicitement vos variables, méthodes, fichiers ou en les indentant correctement ...

Lorsque mes élèves acceptent ce fait, ils arrêtent de se battre contre leur propre code source et commencent à voir le codage comme une activité vraiment intéressante, stimulante et créative. Ils défient leur esprit, pas leurs nerfs!

thomas.g
la source
2

C'est une question de préférence. J'utilise personnellement les deux styles, si je suis raisonnablement sûr que je n'aurai plus besoin d'ajouter d'autres déclarations, j'utilise le premier style, mais si c'est possible, j'utilise le second. Puisque vous ne pouvez plus ajouter de déclarations au premier style, j'ai entendu certaines personnes recommander de ne pas l'utiliser. Cependant, la deuxième méthode implique une ligne de code supplémentaire et si vous (ou votre projet) utilisez ce type de style de codage, la première méthode est très préférée pour les instructions if simples:

if(statement)
{
    do this;
}
else
{
    do this;
}

Cependant, je pense que la meilleure solution à ce problème est en Python. Avec la structure de bloc basée sur des espaces, vous n'avez pas deux méthodes différentes pour créer une instruction if: vous n'en avez qu'une:

if statement:
    do this
else:
    do this

Bien que cela ait le "problème" que vous ne pouvez pas du tout utiliser les accolades, vous avez l'avantage qu'il n'y a plus de lignes que le premier style et qu'il a le pouvoir d'ajouter plus d'instructions.

Grant Paul
la source
Je pense par moi-même que la façon dont Python gère les instructions if-else est très moche, mais là encore, je ne suis pas (encore) programmeur Python
Helpermethod
1

J'ai toujours essayé de rendre mon code standard et de ressembler le plus possible au même. Cela permet aux autres de le lire plus facilement lorsqu'ils sont chargés de le mettre à jour. Si vous faites votre premier exemple et ajoutez une ligne au milieu, cela échouera.

Ne fonctionnera pas:

si (déclaration) faites ceci; et ça; sinon faites ceci;

Joe
la source
1

Personnellement, j'utilise le premier style uniquement pour lancer une exception ou renvoyer prématurément une méthode. Comme argument Vérifier au début d'une fonction, car dans ces cas, j'ai rarement plus d'une chose à faire, et il n'y en a jamais d'autre.

Exemple:

if (argument == null)
    throw new ArgumentNullException("argument");

if (argument < 0)
    return false;

Sinon j'utilise le second style.

Nate Heinrich
la source
1

Ma préférence personnelle utilise un mélange d'espaces et de crochets comme celui-ci:

if( statement ) {

    // let's do this

} else {

    // well that sucks

}

Je pense que cela a l'air propre et rend mon code très facile à lire et, plus important encore, à déboguer.

Simon
la source
0

Je suis d'accord avec la plupart des réponses sur le fait qu'il vaut mieux être explicite dans votre code et utiliser des accolades. Personnellement, j'adopterais un ensemble de normes de codage et je m'assurerais que tous les membres de l'équipe les connaissent et s'y conforment. Là où je travaille, nous utilisons les normes de codage publiées par IDesign.net pour les projets .NET.

Kane
la source
0

Je préfère mettre une attelle frisée. Mais parfois, l'opérateur ternaire aide.

Au lieu de :

int x = 0;
if (condition) {
    x = 30;
} else {
    x = 10;
}

Il faut simplement faire: int x = condition ? 30 : 20;

Imaginez aussi un cas:

if (condition)
    x = 30;
else if (condition1)
    x = 10;
else if (condition2)
    x = 20;

Ce serait beaucoup mieux si vous mettez l'orthèse bouclée.

fastcodejava
la source