2013-10-10 16 views
56

Ho letto alcuni codice legacy:C'è qualche motivo per usare se (1 ||! Foo())?

if (1 || !Foo()) 

C'è qualche motivo per cui visto non scrivere:

if (!Foo()) 
+27

'1 || qualcosa() 'arriverà sempre vero. Quindi le due affermazioni non sono equivalenti, ma sul perché questo è fatto, passa. – SinisterMJ

+10

'if (1 ||! Foo())' <==> 'if (1)'. – devnull

+0

Perché non solo per rimuovere il condizionale? Tu dici che '1 || foo() '==' pippo() '. Ciò significa che il codice dietro di loro è inutile. Puoi rimuoverlo del tutto con le condizioni. – Val

risposta

134

i due non sono lo stesso. Il primo non valuterà mai Foo() perché il 1 cortocircuiti lo ||.

Perché è stato fatto - probabilmente qualcuno ha voluto forzare l'immissione nel ramo then per il debug e lo ha lasciato lì. Potrebbe anche essere che questo è stato scritto prima del controllo del codice sorgente, quindi non volevano che il codice andasse perso, piuttosto semplicemente bypassato per ora.

+23

Suona come qualcosa che è stato inserito durante lo sviluppo/debug e lasciato lì perché qualcuno ha dimenticato di rimuoverlo o per paura di rompere qualcosa. – Medinoc

+0

In ogni caso questa è una soluzione migliore rispetto al commento perché il compilatore continua a controllare il codice inattivo. Lo faccio sempre per motivi di debug. – usr

+0

solo uno sviluppatore davvero esperto lo sa. +1 – Baby

11
1 || condition 

è sempre vero, indipendentemente dal fatto che condition sia vero o meno. In questo caso, lo condition non viene mai nemmeno valutato. Il codice seguente:

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

uscite 5 dal c viene mai incrementato, se è stato modificato 1 a 0, il c++ sarebbe effettivamente chiamati, rendendo l'uscita 6.


un normale utilizzo pratico di questo è nella situazione in cui si vuole testare qualche pezzo di codice che viene richiamato quando la condizione che restituisce true solo raramente è soddisfatta:

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

Questo modo condition non verrà mai valutato e pertanto viene invocato sempre // code I want to test. Tuttavia non è assolutamente la stessa:

if (condition) { ... 

che è una dichiarazione in cui sarà effettivamente essere valutati condition (e nel tuo caso sarà chiamato Foo)

+0

* 'non vuoi aspettare fino a quando questa condizione non valuterà il vero '* sì in pratica i cortocircuiti sono una tecnica per salvare le esecuzioni! –

+0

@GrijeshChauhan: Non mi riferivo alle prestazioni, né al momento dell'esecuzione. Mi riferivo a criteri specifici che sono stati soddisfatti. – LihO

+0

ahi è una strana caratteristica del linguaggio. Credevo che la conding fosse sempre valutata se avesse effetti collaterali (quindi fondamentalmente credevo che i metodi non-const e le funzioni statiche fossero valutati, ma ho provato in un semplice "ciao mondo" e non sono mai riuscito a ottenere una condizione valutata nel primo caso O_O – GameDeveloper

44

if (1 || !Foo()) sarà sempre soddisfatti. !Foo() non sarà nemmeno raggiunto a causa di short-circuits evaluation.

Questo accade quando si vuole fare in modo che venga eseguito il codice sotto il if, ma non si vuole rimuovere il vero condizioni in esso, probabilmente a scopo di debug.

Ulteriori informazioni che potrebbero aiutarvi:

  • if(a && b) - se a è false, non verrà controllato b.
  • if(a && b) - se a è true, b sarà controllato, perché se è false, l'espressione sarà false.
  • if(a || b) - se a è true, non verrà controllato, perché questo è true comunque.
  • if(a || b) - se a è false, b sarà controllato, perché se è btrue allora sarà true.

Si consiglia vivamente di avere una macro per questo scopo, dicono DEBUG_ON 1, che renderà più facile per capire che cosa i mezzi programmatore, e non avere numeri magici nel codice (Grazie @grigeshchauhan).

+6

Quindi 'if (1 ||! Foo()) {codice}' == 'if (1) {codice}' == '{codice}' mentre 'if (! Foo())' può essere o '{code}' o solo ';' dipende dal valore restituito da 'Foo()'. :) –

+0

Estendo le ultime espressioni .. EDIT: per scopi di debug utilizzare una macro 'DEGUG_ON = 1' o commentarla. 'if (DEGUG_ON ||! Foo())' (infatti commenterò il codice). ;) –

+0

* "Si consiglia di avere una macro per questo scopo, ad esempio DEBUG_ON 1" * ... sì eccetto la leggibilità del codice è la tua ultima preoccupazione quando stai cercando di trovare quel dannato bug :-) – Mehrdad

10

La domanda è stata risolta correttamente - la differenza è il lato destro dell'operazione o è cortocircuitata, suggerendo che questo è il codice di debug per forzare l'ingresso nel blocco if.

ma nell'interesse delle migliori pratiche, almeno il mio pugnalata di massima a una best practice, io suggerirei di alternative, in ordine crescente di preferenza (migliore è l'ultima):

nota: notato dopo ho codificato esempi questa era una domanda in C++, gli esempi sono C#. Spero che tu possa tradurre. Se qualcuno ha bisogno di me, basta pubblicare un commento.

In-riga di commento:

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

Out-of-riga di commento:

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

Nome-indicativo Funzione

//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()"))... 

e se si voleva una soluzione davvero robusta, è possibile aggiungere una regola di repository al controllo del codice sorgente per rifiutare qualsiasi codice archiviato denominato ForceConditionForDebug. Questo codice non dovrebbe mai essere stato scritto in quel modo perché ovviamente non comunica l'intento. Non avrebbe mai dovuto essere archiviato (o permesso di essere registrato) (controllo del codice sorgente? Peer review?) E non dovrebbe mai essere permesso di eseguire in produzione nella sua forma attuale.

Problemi correlati