Ma question concerne 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 général 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 quelle est la signification de mettre if (0)
ici. Les accolades sont vides, donc je ne pense pas qu'il soit supposé commenter un bloc de code. Est-ce que cela oblige le compilateur à optimiser ou est-ce que ses intentions sont 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 à propos de JavaScript, mais pas C. Il y a une autre question, Que se passe-t-il lorsqu'un zéro est assigné dans une "condition if"? , mais il traite de l'affectation nulle à une variable, pas le " si (0) 'utilisation elle-même.
J'utilise parfois cela pour des raisons de symétrie afin de pouvoir déplacer l'autre else if{
librement avec l'éditeur sans avoir à me soucier de la première if
.
Sémantiquement le
if (0) {
// Empty braces
} else
partie ne fait rien et vous pouvez compter sur les optimiseurs pour le supprimer.
Cela peut être utile s’il existe des instructions #if
,
if (0)
{
// Empty block
}
#if TEST1_ENABLED
else if (test1())
{
action1();
}
#endif
#if TEST2_ENABLED
else if (test2())
{
action2();
}
#endif
etc.
Dans ce cas, tous les tests (et tous) peuvent être #if
'édités, et le code sera compilé correctement. Presque tous les compilateurs vont supprimer la partie if (0) {}
. 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'est pas nécessaire de considérer le premier bloc activé séparément.
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 clause where
suivante.
where 1 = 1
Cela facilite probablement l'ajout d'autres critères, car tous les critères supplémentaires peuvent être précédés de and
au lieu d'un contrôle supplémentaire pour déterminer s'il s'agit du premier critère ou non.
Comme écrit, la clause if (0) {}
ne compile rien.
Je suppose 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 en même temps (à des fins de débogage ou de comparaison) en remplaçant le 0
par un 1
ou true
.
Une possibilité qui n’a pas encore été mentionnée: la ligne if (0) {
pourrait être un endroit pratique pour un point de rupture.
Le débogage est souvent effectué sur du code non optimisé afin que le test toujours faux soit présent et puisse avoir un point d'arrêt défini. Une fois compilé pour la production, la ligne de code serait optimisée. Cette ligne apparemment inutile fournit des fonctionnalités pour les versions de développement et de test sans impact sur les versions validées.
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 fonctionnalité de type blame
-.)
Je ne suis pas sûr des optimisations, mais mes deux cents:
Cela est dû à une modification du code, dans laquelle une condition principale a été supprimée (l'appel de la fonction dans le bloc initial if
, par exemple), mais les développeurs/responsables
if-else
ainsi, au lieu de supprimer le bloc associé if
, ils ont simplement changé la condition en if(0)
, puis sont passés à autre chose.
C'est du code pourri.
À un moment donné, "si" a fait 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 le faisait le moins possible pour affecter la logique du système alors il s'est assuré que le code serait recompilé. Donc, il laisse un "if (0)" parce que c'est rapide et facile et qu'il n'est pas totalement sûr que c'est ce qu'il veut faire. Il fait fonctionner le système et ne retourne pas le réparer complètement.
Ensuite, le prochain développeur arrive et pense que cela a été fait délibérément et ne commente que cette partie du code (étant donné qu'elle n'est pas évaluée de toute façon), la prochaine fois que le code sera touché, ces commentaires seront supprimés.
J'ai vu des blocs de code non accessibles en 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 peut avoir été collé à partir d'un serveur qui a pré-évalué la première condition qui, à ce moment-là, reposait sur une variable uniquement disponible côté serveur.
if ( ${requestIsNotHttps} ){ ... }else if( ...
qui déjà une fois pré-compilé:
if ( 0 ){ ... }else if ( ...
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 un enthousiasme!
Cette construction peut également être utilisée en C pour implémenter une programmation générique avec le type safety, en s’appuyant sur le fait que le code inaccessible est toujours vérifié par le compilateur:
// this is a generic unsafe function, that will call fun(arg) at a later time
void defer(void *fun, void *arg);
// this is a macro that makes it safer, by checking the argument
// matches the function signature
#define DEFER(f, arg) \
if(0) f(arg); \ // never actually called, but compile-time checked
else defer(f, (void *)arg); // do the unsafe call after safety check
void myfunction(int *p);
DEFER(myfunction, 42); // compile error
int *b;
DEFER(myfunction, b); // compiles OK
Je pense que c'est juste un mauvais code. En écrivant un exemple rapide dans Compiler Explorer, nous voyons qu’à la fois dans gcc et clang, aucun code n’est généré pour le bloc if (0)
, même avec les optimisations complètement désactivées:
Jouer avec supprimer la if (0)
ne provoque aucune modification du code généré, je conclus donc qu'il ne s'agit pas d'une optimisation.
Il est possible qu’il y ait eu quelque chose dans le bloc supérieur if
qui a ensuite été supprimé. En bref, il semble que le supprimer entraînerait la génération exacte du même code, alors n'hésitez pas à le faire.
Comme il a été dit, le zéro est évalué à faux et la branche sera probablement optimisée par le compilateur.
J'ai déjà vu cela auparavant dans le code lorsqu'une nouvelle fonctionnalité a été ajoutée et qu'un kill-switch était nécessaire (si quelque chose ne va pas avec la fonctionnalité, vous pouvez simplement l'éteindre), et quelque temps plus tard, lorsque le kill-switch a été supprimé. le programmeur n'a pas également supprimé la branche, par exemple.
if (feature_a_active()) {
use_feature_a();
} else if (some_fn()) {
...
devenu
if (0) {
// empty
} else if (some_fn()) {
...
La réponse de @ PSkocik est correcte, mais j'ajoute mes deux sous. Je ne sais pas si je devrais le faire comme commentaire ou comme réponse. choisir ce dernier, parce que mon humble avis vaut le voir, alors que les commentaires sont souvent invisibles.
Non seulement j'utilise occasionnellement
if(0) {
//deliberately left empty
} else if( cond1 ) {
//deliberately left empty
} else if( cond2 ) {
//deliberately left empty
...
} else {
// no conditions matched
}
Mais je fais aussi de temps en temps
if( 1
&& cond1
&& cond2
...
&& condN
) {
ou
if( 0
|| cond1
|| cond2
...
|| condN
) {
pour des conditions compliquées. Pour les mêmes raisons - plus facile à modifier, # ifdef, etc.
D'ailleurs, en Perl je ferai
@array = (
elem1,
elem2,
...
elem1,
) {
Je compare le code if(0)
à LISP
(cond (test1 action1)
(test2 action2)
...
(testn actionn))
que vous avez deviné, je peux indenter comme
(cond
(test1 action1)
(test2 action2)
...
(testn actionn)
)
J'ai parfois essayé d'imaginer à quoi pourrait ressembler une syntaxe plus lisible par l'homme.
Peut-être
IF
:: cond1 THEN code1
:: cond2 THEN code2
...
:: condN THEN codeN
FI
inspiré par le [ https://en.wikipedia.org/fr/Guarded_Command_Language#Selection:_if] [Langage de commande gardé ].
Mais cette syntaxe implique que les conditions soient évaluées en parallèle, alors que if...else-if
implique une évaluation séquentielle et priorisée des conditions.
J'ai commencé à faire ce genre de chose en écrivant des programmes générant d'autres programmes, où c'est particulièrement pratique.
Pendant que nous y sommes, en écrivant RTL en utilisant le vieil iHDL d’Intel, j’ai codé des choses comme
IF 0 THEN /*nothing*/
**FORC i FROM 1 TO 10 DOC**
ELSE IF signal%i% THEN
// stuff to do if signal%i% is active
**ENDC**
ELSE
// nothing matched
ENDIF
où FORC..DOC..ENDC
est une construction de boucle de préprocesseur de macro, qui se développe en
IF 0 THEN /*nothing*/
ELSE IF signal1 THEN
// stuff to do if signal1 is active
ELSE IF signal2 THEN
// stuff to do if signal2 is active
...
ELSE IF signal100 THEN
// stuff to do if signal100 is active
ELSE
// nothing matched
ENDIF
Il s'agissait d'un code unique, non impératif, de sorte que la définition d'une variable d'état n'était pas autorisée, si vous deviez effectuer des opérations telles que rechercher le premier bit défini.
IF 0 THEN /*nothing*/
ELSE IF signal1 THEN
found := 1
ELSE IF signal2 THEN
found := 2
...
ELSE IF signal100 THEN
found := 100
ELSE
// nothing matched
ENDIF
À 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-if sont séquentiellement dépendantes et ne peuvent pas être réorganisées arbitrairement - ne s'appliquent pas à AND et OR et XOR la logique dans RTL - mais s’applique aux courts-circuits && et ||.
Actually according to my opinion, if we put any variable for checking inside
e.g:-
public static void main(string args[])
{
var status;
var empList=_unitofWork.EmpRepository.Get(con=>con.isRetired==true);
//some code logic
if(empList.count>0)
{
status=true;
}
if(status)
{
//do something
}
else
{
//do something else
}
}
if then its dynamically get the value in run time and invoke the logic inside it, else its simply extra line of code i guess.
Anybody have any depth knowledge why this thing is used....or agree with me.
kindly respond.
Il est utile de déboguer ce bloc en mettant simplement le bloc 1. Ceci désactive toutes les fonctionnalités du bloc si autrement. Et nous pouvons également élargir le bloc if else.