Notre organisation a une règle de codage obligatoire (sans aucune explication) qui:
if… else if les constructions doivent être terminées par une clause else
Exemple 1:
if ( x < 0 )
{
x = 0;
} /* else not needed */
Exemple 2:
if ( x < 0 )
{
x = 0;
}
else if ( y < 0 )
{
x = 3;
}
else /* this else clause is required, even if the */
{ /* programmer expects this will never be reached */
/* no change in value of x */
}
Quel cas de bord est-ce conçu pour gérer?
Ce qui m'inquiète également à propos de la raison, c'est que l' exemple 1 n'a pas besoin d'un, else
mais que l' exemple 2 en a besoin . Si la raison est la réutilisation et l'extensibilité, je pense qu'il else
devrait être utilisé dans les deux cas.
assert(false, "should never go here")
pourrait avoir du sensif (x < 0) { x = 0; } else { if (y < 0) { x = 3; }}
. Ou vous pouvez simplement suivre de telles règles, dont beaucoup sont stupides, simplement parce que vous y êtes obligé.< 0
vérifications), donc cette affirmation va pour planter le programme dans ce qui est probablement le cas le plus courant où les valeurs sont dans les limites attendues.Réponses:
Comme mentionné dans une autre réponse, cela provient des directives de codage MISRA-C. Le but est la programmation défensive, un concept souvent utilisé dans la programmation critique.
Autrement dit, tout
if - else if
doit se terminer par unelse
, et toutswitch
doit se terminer par undefault
.Il y a deux raisons à cela:
Code auto-documenté. Si vous écrivez un
else
mais que vous le laissez vide, cela signifie: "J'ai définitivement considéré le scénario quand niif
ni neelse if
sont vrais".Ne pas écrire un
else
là signifie: "soit j'ai considéré le scénario où niif
nielse if
n'est vrai, soit j'ai complètement oublié de le considérer et il y a potentiellement un gros bug ici dans mon code".Arrêtez le code emballé. Dans les logiciels critiques, vous devez écrire des programmes robustes qui tiennent compte même des improbables. Ainsi, vous pouvez voir du code comme
Ce code sera complètement étranger aux programmeurs de PC et aux informaticiens, mais il est parfaitement logique dans les logiciels critiques, car il détecte le cas où le "mybool" a été corrompu, pour une raison quelconque.
Historiquement, vous craindriez la corruption de la mémoire RAM à cause des EMI / bruit. Ce n'est pas vraiment un problème aujourd'hui. Beaucoup plus probable, la corruption de la mémoire se produit en raison de bogues ailleurs dans le code: pointeurs vers de mauvais emplacements, bogues de tableau hors limites, débordement de pile, code emballé, etc.
Donc la plupart du temps, un code comme celui-ci revient pour vous gifler lorsque vous avez écrit des bogues lors de la phase d'implémentation. Cela signifie qu'il pourrait également être utilisé comme technique de débogage: le programme que vous écrivez vous avertit lorsque vous avez écrit des bogues.
ÉDITER
En ce qui concerne pourquoi
else
n'est pas nécessaire après chaque simpleif
:Un
if-else
ouif-else if-else
couvre complètement toutes les valeurs possibles qu'une variable peut avoir. Mais uneif
déclaration simple n'est pas nécessairement là pour couvrir toutes les valeurs possibles, elle a un usage beaucoup plus large. Le plus souvent, vous souhaitez simplement vérifier une certaine condition et si elle n'est pas remplie, ne faites rien. Ensuite, il n'est tout simplement pas significatif d'écrire une programmation défensive pour couvrir leelse
cas.De plus, cela encombrerait complètement le code si vous écriviez un vide
else
après chaqueif
.MISRA-C: 2012 15.7 ne donne aucune raison pour laquelle ce
else
n'est pas nécessaire, il déclare simplement:la source
if/else if/else
compilé ce que vous attendez? Et puis un autre pour vérifier le vérificateur précédent également?mybool
n'ait un type non booléen, comme c'était le cas avant que C obtienne le sienbool
; alors le compilateur ne ferait pas l'hypothèse sans une analyse statique supplémentaire). Et au sujet de 'Si vous écrivez un autre mais laissez-le vide, cela signifie: "J'ai définitivement considéré le scénario quand ni si ni else si sont vrais".': Ma première réaction est de supposer que le programmeur a oublié de mettre du code dans le bloc else, sinon pourquoi avoir un bloc else vide juste assis là? Un// unused
commentaire serait approprié, pas seulement un bloc vide.else
bloc doit contenir une sorte de commentaire s'il n'y a pas de code. La pratique courante pour videelse
est un point - virgule , plus un commentaire:else { ; // doesn't matter }
. Comme il n'y a aucune raison pour que quelqu'un d'autre taperait simplement un point-virgule unique en retrait sur une ligne qui lui est propre. Pratique similaire est parfois utilisé dans les boucles vides:while(something) { ; // do nothing }
. (code avec sauts de ligne, évidemment. SO les commentaires ne les autorisent pas)Votre entreprise a suivi les directives de codage MISRA. Il existe quelques versions de ces directives qui contiennent cette règle, mais d'après MISRA-C: 2004 † :
Dans MISRA-C: 2012 , qui remplace la version 2004 et est la recommandation actuelle pour les nouveaux projets, la même règle existe mais porte le numéro 15.7 .
Exemple 1: dans une seule instruction if, le programmeur peut avoir besoin de vérifier n nombre de conditions et d'effectuer une seule opération.
Dans une utilisation régulière, l'exécution d'une opération n'est pas nécessaire tout le temps lorsqu'elle
if
est utilisée.Exemple 2: Ici, le programmeur vérifie n nombre de conditions et effectue plusieurs opérations. Dans l' usage régulier
if..else if
est commeswitch
vous devrez peut - être effectuer une opération comme par défaut. Donc, l'utilisationelse
est nécessaire selon la norme misra† Les versions actuelles et passées de ces publications sont disponibles à l'achat via la boutique en ligne MISRA ( via ).
la source
else
clause ne soit pas accessible? (Oubliez la condition finale à la place, lancez une erreur, peut-être?)Ce supplément réduira la couverture du code de votre programme.
Dans mon expérience avec le portage du noyau Linux ou du code Android sur différentes plates-formes, nous faisons souvent quelque chose de mal et dans logcat, nous voyons une erreur comme
la source
__FILE__
que les__LINE__
macros sont utiles pour faciliter la recherche de l'emplacement source si le message est imprimé.Juste une brève explication, puisque j'ai fait tout cela il y a environ 5 ans.
Il n'y a (avec la plupart des langages) aucune exigence syntaxique d'inclure une
else
déclaration «nulle» (et inutile{..}
), et dans les «petits programmes simples», ce n'est pas nécessaire. Mais les vrais programmeurs n'écrivent pas de "petits programmes simples" et, tout aussi important, ils n'écrivent pas de programmes qui seront utilisés une fois et ensuite rejetés.Quand on écrit un if / else:
tout semble simple et on ne voit même pas l'intérêt d'ajouter
{..}
.Mais un jour, dans quelques mois, un autre programmeur (vous ne feriez jamais une telle erreur!) Devra "améliorer" le programme et ajoutera une déclaration.
Soudain,
doSomethingElse
oublie un peu que c'est censé être dans laelse
jambe.Vous êtes donc un bon petit programmeur et vous utilisez toujours
{..}
. Mais vous écrivez:Tout va bien jusqu'à ce que ce nouvel enfant fasse une modification à minuit:
Oui, il est mal formaté, mais la moitié du code du projet l'est aussi, et le "formateur automatique" est bollixé par toutes les
#ifdef
instructions. Et, bien sûr, le vrai code est beaucoup plus compliqué que cet exemple de jouet.Malheureusement (ou pas), je suis hors de ce genre de choses depuis quelques années maintenant, donc je n'ai pas un nouvel exemple "réel" en tête - ce qui précède est (évidemment) artificiel et un peu hokey.
la source
Ceci est fait pour rendre le code plus lisible, pour les références ultérieures et à préciser, à un avis plus tard, que les autres cas traités par le dernier
else
, sont ne font rien des cas, de sorte qu'ils ne soient pas négligés en quelque sorte à première vue.Il s'agit d'une bonne pratique de programmation, qui rend le code réutilisable et extensible .
la source
Je voudrais ajouter - et contredire en partie - les réponses précédentes. Bien qu'il soit certainement courant d'utiliser if-else if d'une manière de type interrupteur qui devrait couvrir l'ensemble des valeurs imaginables d'une expression, il n'est en aucun cas garanti que toute plage de conditions possibles soit entièrement couverte. La même chose peut être dite à propos de la construction du commutateur elle-même, d'où l'exigence d'utiliser une clause par défaut, qui capture toutes les valeurs restantes et peut, si ce n'est pas nécessaire de toute façon, être utilisée comme sauvegarde d'assertion.
La question elle-même présente un bon contre-exemple: la deuxième condition ne concerne pas du tout x (c'est la raison pour laquelle je préfère souvent la variante basée sur if plus flexible à la variante basée sur le commutateur). D'après l'exemple, il est évident que si la condition A est remplie, x doit être mis à une certaine valeur. Si A n'est pas satisfait, la condition B est testée. S'il est satisfait, alors x devrait recevoir une autre valeur. Si ni A ni B ne sont satisfaits, alors x doit rester inchangé.
Ici, nous pouvons voir qu'une branche else vide doit être utilisée pour commenter l'intention du programmeur pour le lecteur.
D'un autre côté, je ne vois pas pourquoi il doit y avoir une clause else, en particulier pour la dernière et la plus profonde déclaration if. En C, il n'y a pas de «sinon si». Il n'y a que si et autre. Au lieu de cela, selon MISRA, la construction devrait formellement être indentée de cette façon (et j'aurais dû mettre les accolades d'ouverture sur leurs propres lignes, mais je n'aime pas ça):
Quand MISRA demande de mettre des accolades autour de chaque branche, alors il se contredit en mentionnant "if ... else if constructs".
N'importe qui peut imaginer la laideur des arbres if else profondément imbriqués, voir ici sur une note latérale . Imaginez maintenant que cette construction puisse être étendue arbitrairement n'importe où. Ensuite, demander une clause else à la fin, mais pas ailleurs, devient absurde.
Je suis donc sûr que les personnes qui ont développé les lignes directrices MISRA avaient l'intention de passer si-sinon si à l'esprit.
En fin de compte, il leur revient de définir précisément ce que l'on entend par "if ... else if construct"
la source
La raison fondamentale est probablement la couverture du code et le else implicite: comment le code se comportera-t-il si la condition n'est pas vraie? Pour des tests authentiques, vous avez besoin d'un moyen de voir que vous avez testé avec la condition false. Si chaque scénario de test que vous avez passe par la clause if, votre code peut avoir des problèmes dans le monde réel en raison d'une condition que vous n'avez pas testée.
Cependant, certaines conditions peuvent ressembler à l'exemple 1, comme sur une déclaration de revenus: «Si le résultat est inférieur à 0, entrez 0». Vous devez toujours avoir un test où la condition est fausse.
la source
Logiquement, tout test implique deux branches. Que faites-vous si c'est vrai et que faites-vous si c'est faux.
Pour les cas où l'une ou l'autre des branches n'a aucune fonctionnalité, il est raisonnable d'ajouter un commentaire expliquant pourquoi elle n'a pas besoin de fonctionnalités.
Cela peut être avantageux pour le prochain programmeur de maintenance à venir. Ils ne devraient pas avoir à chercher trop loin pour décider si le code est correct. Vous pouvez en quelque sorte Prehunt the Elephant .
Personnellement, cela m'aide car cela m'oblige à regarder l'autre cas et à l'évaluer. Cela peut être une condition impossible, auquel cas je peux lever une exception car le contrat est violé. Cela peut être bénin, auquel cas un commentaire peut suffire.
Votre kilométrage peut varier.
la source
La plupart du temps, lorsque vous n'avez qu'une seule
if
déclaration, c'est probablement l'une des raisons telles que:Exemple
Mais quand vous le faites
if .. else if
, c'est probablement l'une des raisons telles que:Et si votre
if .. else if
couverture couvre toutes les possibilités, dans ce cas votre dernièreif (...)
n'est pas nécessaire, vous pouvez simplement la supprimer, car à ce stade, les seules valeurs possibles sont celles couvertes par cette condition.Exemple
Et dans la plupart de ces raisons, il est possible que quelque chose ne rentre dans aucune des catégories de votre
if .. else if
, donc la nécessité de les gérer dans uneelse
clause finale , le traitement peut être effectué via une procédure au niveau de l'entreprise, une notification utilisateur, un mécanisme d'erreur interne, ..etc.Exemple
Cette dernière
else
clause est assez similaire à peu d'autres choses dans des langages tels queJava
etC++
, tels que:default
case dans une instruction switchcatch(...)
qui vient après tous lescatch
blocs spécifiquesfinally
dans une clause try-catchla source
Notre logiciel n'était pas essentiel à la mission, mais nous avons également décidé d'utiliser cette règle en raison d'une programmation défensive. Nous avons ajouté une exception throw au code théoriquement inaccessible (switch + if-else). Et cela nous a sauvé de nombreuses fois car le logiciel a échoué rapidement, par exemple lorsqu'un nouveau type a été ajouté et que nous avons oublié de changer un ou deux if-else ou de changer. En prime, il a été très facile de trouver le problème.
la source
Eh bien, mon exemple implique un comportement non défini, mais parfois certaines personnes essaient d'être fantaisistes et échouent dur, jetez un coup d'œil:
Vous ne vous attendriez probablement jamais à avoir
bool
ce qui n'est pas nontrue
plusfalse
, mais cela peut arriver. Personnellement, je pense que c'est un problème causé par une personne qui décide de faire quelque chose de sophistiqué, mais uneelse
déclaration supplémentaire peut empêcher d'autres problèmes.la source
Je travaille actuellement avec PHP. Création d'un formulaire d'inscription et d'un formulaire de connexion. Je n'utilise que si et autrement. Pas d'autre si ou quoi que ce soit qui est inutile.
Si l'utilisateur clique sur le bouton Soumettre -> il passe à l'instruction if suivante ... si le nom d'utilisateur est inférieur au nombre de caractères «X», alerte. En cas de succès, vérifiez la longueur du mot de passe et ainsi de suite.
Pas besoin de code supplémentaire tel qu'un autre si cela pourrait compromettre la fiabilité du temps de chargement du serveur pour vérifier tout le code supplémentaire.
la source