Ich habe etwas Legacy-Code gelesen:
if ( 1 || !Foo() )
Gibt es einen ersichtlichen Grund, warum man nicht schreibt:
if ( !Foo() )
Elad Benda
Ich habe etwas Legacy-Code gelesen:
if ( 1 || !Foo() )
Gibt es einen ersichtlichen Grund, warum man nicht schreibt:
if ( !Foo() )
Die beiden sind nicht das Gleiche. Der erste wird niemals evaluieren Foo()
weil die 1
Kurzschlüsse die ||
.
Warum es so ist – vermutlich wollte jemand den Zutritt erzwingen then
Verzweigung zu Debugging-Zwecken und beließ sie dort. Es könnte auch sein, dass dies vor der Quellcodeverwaltung geschrieben wurde, also wollten sie nicht, dass der Code verloren geht, sondern nur umgangen wird zur Zeit.
Klingt nach etwas, das während der Entwicklung/dem Debuggen eingefügt und dort gelassen wurde, entweder weil jemand vergessen hat, es zu entfernen, oder aus Angst, etwas zu beschädigen.
– Medinoc
10. Oktober 2013 um 9:45 Uhr
In jedem Fall ist dies eine bessere Lösung als das Auskommentieren, da der Compiler den inaktiven Code ständig überprüft. Ich mache das die ganze Zeit aus Debugging-Gründen.
– usr
24. November 2013 um 17:33 Uhr
nur wirklich erfahrene Entwickler wissen das. +1
– Baby
27. März 2014 um 9:23 Uhr
Maroun
if (1 || !Foo() )
wird immer zufrieden sein. !Foo()
wird nicht einmal wegen erreicht werden Kurzschlussauswertung.
Dies geschieht, wenn Sie sicherstellen möchten, dass der Code unter dem if
wird ausgeführt, aber Sie möchten die nicht entfernen real Bedingung darin, wahrscheinlich für Debug-Zwecke.
Zusätzliche Informationen, die Ihnen helfen könnten:
if(a && b)
– wenn a
ist false
, b
wird nicht geprüft. if(a && b)
– wenn a
ist true
, b
wird überprüft, denn wenn es ist false
wird der Ausdruck sein false
.if(a || b)
– wenn a
ist true
, b
wird nicht überprüft, weil dies der Fall ist true
ohnehin.if(a || b)
– wenn a
ist false
, b
wird überprüft, denn wenn b
ist true
dann wird es sein true
.Es wird beispielsweise dringend empfohlen, ein Makro für diesen Zweck zu haben DEBUG_ON 1
das macht es einfacher zu verstehen, was der Programmierer meint, und nicht zu haben magische Zahlen im Code (Danke @grigeshchauhan).
So if(1 || !Foo() ) {code}
== if(1){code}
== {code}
während if (!Foo())
Kann beides sein {code}
oder nur ;
hängt vom Wert ab, der von zurückgegeben wird Foo()
. 🙂
– Grijesh Chauhan
10. Oktober 2013 um 9:56 Uhr
Ich erweitere Ihre letzten Ausdrücke. BEARBEITEN: Verwenden Sie zum Debuggen entweder ein Makro DEGUG_ON = 1
oder kommentiere es. if (DEGUG_ON || !Foo())
(tatsächlich werde ich Code kommentieren). 😉
– Grijesh Chauhan
10. Oktober 2013 um 14:52 Uhr
“Es wird dringend empfohlen, für diesen Zweck ein Makro zu haben, sagen wir DEBUG_ON 1”… ja, außer dass die Lesbarkeit des Codes Ihre letzte Sorge ist, wenn Sie versuchen, diesen verdammten Fehler zu finden 🙂
– Benutzer541686
16. Oktober 2013 um 8:47 Uhr
@Mehrdad In der Tat. Aber diese Fehlerprüfung könnte selbst zu einem Fehler werden. Oder eine Verwirrung stiften, wie sie bei OP 😀
– Marun
16. Oktober 2013 um 8:49 Uhr
Liho
1 || condition
gilt immer, egal ob die condition
wahr ist oder nicht. In diesem Fall ist die condition
wird auch nie ausgewertet. Der folgende Code:
int c = 5;
if (1 || c++){}
printf("%d", c);
Ausgänge 5
seit c
wird nie erhöht, jedoch wenn Sie sich geändert haben 1
zu 0
das c++
würde tatsächlich aufgerufen werden, wodurch die Ausgabe erfolgt 6
.
Eine übliche praktische Verwendung davon ist in der Situation, wenn Sie einen Codeabschnitt testen möchten, der aufgerufen wird, wenn die Bedingung, die als wahr ausgewertet wird, nur selten erfüllt ist:
if (1 || condition ) {
// code I want to test
}
Diesen Weg condition
wird nie ausgewertet und daher // code I want to test
immer aufgerufen. Es ist jedoch definitiv nicht dasselbe wie:
if (condition) { ...
das ist eine Aussage wo condition
wird tatsächlich ausgewertet (und in Ihrem Fall Foo
wird angerufen werden)
you don't want to wait till that condition will evaluate to true
Ja, Kurzschlüsse sind im Grunde eine Technik, um Hinrichtungen zu retten!
– Grijesh Chauhan
10. Oktober 2013 um 10:06 Uhr
@GrijeshChauhan: Ich bezog mich weder auf die Leistung noch auf den Zeitpunkt der Ausführung. Ich bezog mich auf bestimmte Kriterien, die erfüllt wurden.
– Liho
10. Oktober 2013 um 10:13 Uhr
Autsch, das ist eine seltsame Sprachfunktion. Ich glaubte, dass die Bedingung immer ausgewertet wurde, wenn sie Nebenwirkungen hatte (also glaubte ich im Grunde, dass nicht-konstante Methoden und statische Funktionen ausgewertet wurden, aber ich versuchte es in einer einfachen “Hallo Welt” und konnte nie eine Bedingung in der erster Fall O_O
– KaffeeEntwickler
12. Oktober 2013 um 8:59 Uhr
PatrickV
Die Frage wurde richtig beantwortet – der Unterschied besteht darin, dass die rechte Seite der or-Operation kurzgeschlossen ist, was darauf hindeutet, dass dies ein Debug-Code ist, um den Eintritt in den if-Block zu erzwingen.
Aber im Interesse von Best Practices, zumindest meinem groben Stich in eine Best Practice, würde ich Alternativen in der Reihenfolge zunehmender Präferenz vorschlagen (das Beste kommt zuletzt):
Hinweis: Nachdem ich Beispiele codiert habe, ist mir aufgefallen, dass dies eine C++-Frage war, Beispiele sind C#. Hoffentlich kannst du übersetzen. Wenn mich jemand braucht, poste einfach einen Kommentar.
Inline-Kommentar:
if (1 /*condition*/) //temporary debug
Out-of-line-Kommentar:
//if(condition)
if(true) //temporary debug
Namensgebende Funktion
//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()"))...
Und wenn Sie eine wirklich robuste Lösung wollten, könnten Sie der Quellcodeverwaltung eine Repository-Regel hinzufügen, um jeden eingecheckten Code abzulehnen, der ForceConditionForDebug aufruft. Dieser Code hätte niemals so geschrieben werden dürfen, da er offensichtlich keine Absicht kommuniziert. Es hätte niemals eingecheckt werden dürfen (oder eingecheckt werden dürfen) (Quellcodeverwaltung? Peer-Review?) Und es sollte auf keinen Fall in der aktuellen Form in der Produktion ausgeführt werden dürfen.
‘1 || irgendetwas()’ ergibt immer true. Die beiden Aussagen sind also nicht äquivalent, aber warum das so ist, passe.
– SinisterMJ
10. Oktober 2013 um 9:43 Uhr
if (1 || !foo())
<==>if (1)
.– devnull
10. Oktober 2013 um 9:45 Uhr
Höchstwahrscheinlich wurde dies vorübergehend getan, um die Bedingung auf wahr zu zwingen (vielleicht ein Fehler, eine Problemumgehung oder ein Refactoring) und nicht zurückgesetzt. Verwenden Sie die Anmerkungs-/Schuldfunktion Ihrer Quellcodeverwaltung, um die Version zu finden, in der sich dies geändert hat – Sie erhalten möglicherweise einen nützlichen Kommentar oder Fehlerdatenbankeintrag, um herauszufinden, warum es geändert wurde
– der_Mandrill
10. Oktober 2013 um 13:52 Uhr
Vielleicht ist Foo() so implementiert
return rand() % 2;
– Happy Green Kid Nickerchen
10. Oktober 2013 um 16:27 Uhr
1 && !Foo()
ist gleich!Foo()
– Nikolas R
12. Oktober 2013 um 9:10 Uhr