56 votes

Y a-t-il une raison d'utiliser if (1 ||! Foo ())?

J'ai lu un code hérité:

 if ( 1 || !Foo() )
 

Y a-t-il une raison vue pourquoi ne pas écrire:

 if ( !Foo() )
 

134voto

Luchian Grigore Points 136646

Les deux ne sont pas les mêmes. Le premier n'évaluera jamais Foo() car les 1 court-circuitent les || .

Pourquoi c'est fait - probablement quelqu'un voulait forcer l'entrée dans la branche then à des fins de débogage et l'a laissé là. Il se peut également que cela ait été écrit avant le contrôle de code source. Ils ne voulaient donc pas que le code soit perdu, mais simplement ignoré pour le moment .

44voto

Maroun Maroun Points 31217

if (1 || !Foo() ) seront toujours satisfaits. !Foo() ne sera pas atteint en raison des courts-circuits de l'évaluation.

Ce qui se passe lorsque vous voulez vous assurer que le code ci-dessous l' if seront exécutés, mais vous ne voulez pas supprimer la véritable condition, probablement à des fins de débogage.

D'autres renseignements qui pourraient vous aider:

  • if(a && b) - si a est false, b ne sera pas vérifiée.
  • if(a && b) - si a est true, b sera vérifié, parce que si c'est false, l'expression sera false.
  • if(a || b) - si a est true, b ne sera pas vérifiée, parce que c'est true de toute façon.
  • if(a || b) - si a est false, b sera vérifiée, parce que si b est true ensuite, il sera true.

Il est fortement recommandé d'avoir une macro pour cela, dire DEBUG_ON 1, qui permettra de faire plus facile de comprendre ce que le programmeur a les moyens, et ne pas avoir des numéros de magie dans le code (Merci @grigeshchauhan).

11voto

LihO Points 21648
1 || condition

est toujours vrai, peu importe que l' condition est vrai ou pas. Dans ce cas, l' condition n'est jamais, même en cours d'évaluation. Le code suivant:

int c = 5;
if (1 || c++){}
printf("%d", c);

sorties 5 depuis c n'est jamais incrémenté, cependant si vous avez changé d' 1 de 0, c++ serait en fait appelé, la sortie 6.


Une habitude de l'utilisation pratique de ce qui est dans le cas où vous souhaitez tester un morceau de code qui est invoquée lorsque la condition qui renvoie vrai que c'est rarement rencontré:

if (1 || condition ) {
    // code I want to test
}

De cette façon, condition ne sera jamais évalué et, par conséquent, // code I want to test toujours invoquée. Mais ce n'est certainement pas la même chose que:

if (condition) { ...

qui est une déclaration où condition sera effectivement évalué (et dans votre cas Foo sera appelé).

10voto

PatrickV Points 999

La question a été répondue correctement - la différence, c'est le côté droit de l'opération ou de court-circuit, ce qui suggère c'est de débogage de code pour forcer l'entrée dans le bloc if.

Mais dans l'intérêt de meilleures pratiques, au moins mon rude coup à un les meilleures pratiques, je vous suggère de solutions de rechange, dans l'ordre croissant de préférence (le meilleur est le dernier):

remarque: remarqué après j'ai codé des exemples, ce fut un C++ question, les exemples sont en C#. Nous espérons que vous pouvez traduire. Si quelqu'un a besoin de moi, il vous suffit de poster un commentaire.

Commentaire sur la ligne:

if (1 /*condition*/) //temporary debug

Hors-ligne de commentaire:

//if(condition)
if(true) //temporary debug

Nom-Fonction Indicative

//in some general-use container
bool ForceConditionForDebug(bool forcedResult, string IgnoredResult)
{
      #if DEBUG
          Debug.WriteLine(
              string.Format(
                  "Conditional {0} forced to {1} for debug purposes",
                  IgnoredResult,
                  forcedResult));
          return forcedResult;
      #else
          #if ALLOW_DEBUG_CODE_IN_RELEASE
              return forcedResult;
          #else
              throw new ApplicationException("Debug code detected in release mode");
          #endif
      #endif
}

//Where used
if(ForceConditionForDebug(true, "condition"))...

//Our case
if(ForceConditionForDebug(true, "!Foo()"))...

Et si vous voulez vraiment une solution robuste, vous pouvez ajouter un référentiel de la règle de contrôle de la source de rejeter tout vérifié dans le code qui a appelé ForceConditionForDebug. Ce code ne devrait jamais avoir été écrit de cette façon parce qu'il n'a évidemment pas communiquer leurs intentions. Il n'aurait jamais été enregistré (ou ont été autorisés à être vérifié) (contrôle de code source? examen par les pairs?) Et il devrait certainement jamais être autorisé à exécuter dans la production, dans sa forme actuelle.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X