Ist es jemals in Ordnung, wenn eine Bedingung Nebenwirkungen hat? [geschlossen]

10

Ich nehme an einem Zwischenkurs für Datenstrukturen teil, um an einer Universität teilnehmen zu können, von der jeder in Amerika gehört hat. Eine Codezeile, die im Unterricht geschrieben wurde, fiel mir auf:

if (a > 33 | b++ < 54) {...}

Dies würde keine Codeüberprüfung an meinem Arbeitsplatz bestehen. Wenn Sie in einem Interview Code wie diesen schreiben würden, wäre dies ein bedeutender Schlag gegen Sie. (Es ist nicht nur eine Bedingung mit Nebenwirkungen, sondern auch klug auf Kosten der Klarheit.)

Tatsächlich habe ich noch nie eine Bedingung mit Nebenwirkungen gesehen, und Googeln taucht auch nicht viel auf. Ein anderer Schüler blieb nach dem Unterricht zurück, um auch danach zu fragen, also bin ich nicht der einzige, der das für komisch hielt. Aber der Professor war ziemlich fest davon überzeugt, dass dies ein akzeptabler Code war und dass er so etwas bei der Arbeit schreiben würde. (Sein FT-Job ist als Principal SWE in einem Unternehmen, von dem Sie alle gehört haben.)

Ich kann mir keine Welt vorstellen, in der diese Codezeile jemals akzeptabel oder gar wünschenswert wäre. Liege ich falsch? Ist das ok? Was ist mit dem allgemeineren Fall: Bedingungen mit Nebenwirkungen? Sind die jemals in Ordnung?

rianjs
quelle
7
Diese Linie sollte aus dem Orbit entfernt werden. Zweimal für ein gutes Maß.
Blrfl
8
A nit: Ein einzelnes Rohr (vertikaler Balken) ist ein bitweises oder in den meisten Sprachen eher ein logisches "oder". Es schließt nicht kurz, wenn die linke Seite wahr ist. Da diese Bedingung auf der rechten Seite Nebenwirkungen hat, macht sie einen besonders großen Unterschied im Ergebnis.
Jonathan Eunice
2
Es gibt Redewendungen in verschiedenen Sprachen, die in diese Kategorie fallen würden, aber weil sie "bekannt" oder "normal" sind, verursachen sie keine Probleme. Die Zeile in der Frage scheint nicht in die Kategorie der idiomatischen Verwendung zu fallen, daher würde ich sie vermeiden.
Jaydee
2
@ JonathanEunice, ja, einige Leute waren verwirrt über die Kurzschlussbewertung. Kein Tippfehler meinerseits.
Rianjs
5
Schau auf die angenehme Seite. Sie kennen jetzt eine weitere Firma, in der Sie NICHT interviewen möchten.
John R. Strohm

Antworten:

23

Es gibt einen halbbedingten Nebeneffekt, den ich mir vorstellen kann, der in Ordnung ist:while(iter.MoveNext())

Trotzdem denke ich, dass dies hauptsächlich in die Kategorie " Nie ist ein wirklich großes Qualifikationsspiel" fällt . Ich kann mir einige seltene Fälle vorstellen, in denen ich gesehen habe, dass dies akzeptabel ist, aber im Allgemeinen ist dies abscheulich und sollte vermieden werden.

Ich kann mir auch kein Szenario vorstellen, in dem diese bestimmte Zeile akzeptabel wäre, aber ich kann mir auch kein Szenario vorstellen, in dem diese bestimmte Zeile nützlich wäre , so dass es schwer vorstellbar ist, in welchem Kontext sie sich befindet.

Telastyn
quelle
Es war nur eine Wegwerflinie in einer Methode während des Unterrichts. Es war nicht beabsichtigt, etwas Nützliches zu tun.
Rianjs
4
Entsprechend sind while(v = *p++)Scans im C / C ++ - Stil durch ein Array mit Nulltermin (z. B. C-String) weit verbreitet und weit verbreitet.
Phil Miller
3
Ich habe Schleifenbedingungen der Form oft als while(c = input.read() != '\n')einigermaßen idiomatisch angesehen.
1
Es mag ein paar allgemein akzeptable Redewendungen geben, aber es fällt eindeutig in das NIEMALS-Lager, "auf Kosten der Klarheit klug zu sein".
Julia Hayward
Ich habe iter.MoveNext () total vergessen. Ein völlig vernünftiger Fall für eine Bedingung mit Nebenwirkung. Vielen Dank!
Rianjs
8

In meiner Welt kann ein Lesen aus dem Speicher als Nebeneffekt angesehen werden (z. B. speicherabgebildete E / A).

Betrachten Sie nun Folgendes:

    while( ( *memory_mapped_device_status_register & READY_FLAG) == 0) {
       // Wait
    }

Und vergleiche mit:

    status = *memory_mapped_device_status_register;
    while( ( status & READY_FLAG) == 0) {
        // Wait
        status = *memory_mapped_device_status_register;
    }

Hat das Vermeiden der Nebenwirkung (des Lesens) in der Bedingung die Lesbarkeit verbessert? oder hat es nur Code dupliziert und Unordnung hinzugefügt?

Es ist nicht in Ordnung, wenn eine Bedingung Nebenwirkungen hat (wenn dies den Code weniger lesbar macht), und es ist auch in Ordnung, wenn eine Bedingung Nebenwirkungen hat (wenn dies den Code lesbarer macht). Der Schlüsselfaktor ist "Lesbarkeit". Alles andere sind Regeln, die von Dummköpfen in einem fehlgeleiteten Versuch erstellt wurden, die Lesbarkeit zu verbessern (und oft den gegenteiligen Effekt haben).

Brendan
quelle
3

Wie immer bei solchen Fragen ist dies eine Frage des Grades. Wenn es eindeutiger Beweis war , dass jede Nebenwirkung in einem ifAusdruck immer zu schlechten Code geführt, dann wäre es nicht legal sein , diese Ausdrücke zu erstellen. Sprachdesigner mögen ideosynkratische, fehlbare Menschen sein, aber sie sind nicht so dumm.

Was sind jedoch Beispiele für gerechtfertigte Nebenwirkungen innerhalb eines if? Angenommen, Sie sind gesetzlich verpflichtet, den gesamten Zugriff auf das Eigentum Peines Unternehmens Ezu Prüfungszwecken aufzuzeichnen . (Stellen Sie sich vor, Sie arbeiten in einer Urananreicherungsanlage, und es gibt sehr strenge gesetzliche Kontrollen darüber, was Ihr Code tun darf und wie er es tun soll.) ifWenn Sie diese Eigenschaft überprüfen, verursacht dies die Nebenwirkung von Überwachungsprotokoll wird erweitert.

Das ist ein ziemlich klares Querschnittsthema, es hat keinen Einfluss auf Ihre Überlegungen zum Programmstatus (sehr), und Sie können es so implementieren, dass es völlig unsichtbar und nicht ablenkend ist, wenn Sie die Zeile mit dem if(ausgeblendeten) überprüfen im Accessor oder noch besser über AOP). Ich würde sagen, das ist ein ziemlich klarer Fall einer Nebenwirkung, die kein Problem darstellt. Ähnliche Situationen können Sie sich vorstellen, wenn Sie nur Zweigausführungen für Profilierungszwecke usw. zählen möchten.

Je mehr diese mildernden Umstände verschwinden, desto seltsamer wird das Konstrukt. Wenn ein bestimmter Schleifentyp (z. B. if((c = getc()) == 'x') { quit(); }bekannt und von der Sprachgemeinschaft akzeptiert) viel weniger problematisch ist als wenn Sie ihn spontan erfinden usw. Ihre Beispielzeile entspricht nicht diesem Standard, aber ich könnte mir viel, viel vorstellen schrecklichere, die ich nicht einmal tippen werde, sie sind so schrecklich.

Kilian Foth
quelle
2

Obwohl es sich um wirklich stinkenden Code handelt, hat er den Vorteil, dass er einfacher (und möglicherweise schneller, wenn Sie keinen guten optimierenden Compiler haben) als der entsprechende Code ist if (a > 33 | b < 54) {b++; ...} else b++;

aber natürlich ist es möglich, es auf folgendes zu optimieren (aber aufgepasst! dieses hat ein anderes Verhalten im Falle eines Überlaufs!): b++; if (a > 33 | b < 53) {...}

Franki
quelle