In letzter Zeit habe ich viele Fragen zur Ausgabe von einigen verrückten und dennoch syntaktisch zulässigen Codeanweisungen wie i = ++i + 1
und i=(i,i++,i)+1;
gestellt.
Ehrlich gesagt schreibt kaum jemand irgendeinen solchen Code in die eigentliche Programmierung. Um ehrlich zu sein, habe ich in meiner beruflichen Erfahrung noch nie einen solchen Code kennengelernt. So überspringe ich normalerweise solche Fragen hier auf SO. Aber in letzter Zeit lässt mich das bloße Volumen solcher Qs denken, wenn ich eine wichtige Theorie verpasse, indem ich solche Qs überspringe. Ich nehme an, dass die Qs sich um Sequence points
drehen. Ich weiß kaum etwas über Sequenzpunkte, um ehrlich zu sein, und ich frage mich nur, ob es nicht in irgendeiner Weise ein Handicap ist, wenn ich es nicht weiß. Also kann jemand bitte die Theorie / das Konzept von Sequence points
erklären, oder wenn möglich auf eine Ressource zeigen, die über das Konzept erklärt. Lohnt es sich auch, Zeit in das Wissen über dieses Konzept / Theorie zu investieren?
Die einfachste Antwort, die ich mir vorstellen kann, ist:
C ++ ist in Form einer abstrakten Maschine definiert. Die Ausgabe eines Programms, das auf der abstrakten Maschine ausgeführt wird, ist NUR in der Reihenfolge definiert, in der "Nebenwirkungen" ausgeführt werden. Und Nebeneffekte sind definiert als Aufrufe in IO-Bibliotheksfunktionen und Änderungen an Variablen, die als flüchtig gekennzeichnet sind.
C ++ - Compiler dürfen intern alles machen, was sie wollen, um den Code zu optimieren, aber sie können nicht die Reihenfolge der Schreibvorgänge in flüchtige Variablen und io-Aufrufe ändern.
Sequenzpunkte definieren den Heartbeat des c / c ++ - Programms - Nebenwirkungen vor dem Sequenzpunkt sind "abgeschlossen" und Nebenwirkungen nach dem Sequenzpunkt sind noch nicht erfolgt. Aber Seiteneffekte (oder Code, der indirekt einen Nebeneffekt bewirken kann, innerhalb eines Sequenzpunkts können neu geordnet werden.
Deshalb ist es wichtig, sie zu verstehen. Ohne dieses Verständnis ist Ihr grundlegendes Verständnis, was ein C ++ Programm ist (und wie es von einem aggressiven Compiler optimiert werden könnte) fehlerhaft.
Siehe Ссылка .
Es ist ein ziemlich einfaches Konzept, so dass Sie nicht viel Zeit investieren müssen:)
Die genauen technischen Details der Sequenzpunkte können haarig werden, ja. Die Befolgung dieser Richtlinie löst jedoch fast alle praktischen Probleme:
Hier beinhaltet "Modifikation" Zuweisungsoperationen für den linken Wert in =
, +=
usw. sowie die Syntax ++x
, x++
, --x
und x--
. (Es sind normalerweise diese Inkrement / Dekrement-Ausdrücke, bei denen einige Leute versuchen, clever zu sein und in Schwierigkeiten geraten.)
Glücklicherweise gibt es Sequenzpunkte an den meisten "erwarteten" Orten:
&&
und ||
. ?
in einem ternären Ausdruck. ,
. (Am häufigsten in für Bedingungen gesehen, z. B. for (a=0, b=0; a<m && b<n; ++a, ++b)
.) Ein Komma, das Funktionsargumente trennt, ist nicht der Kommaoperator und ist nicht ein Sequenzpunkt. Überladene operator&&
, operator||
und operator,
verursachen keine Sequenzpunkte. Mögliche Überraschungen aus dieser Tatsache sind ein Grund, warum Überlastung in der Regel nicht erwünscht ist.
Es ist wissenswert, dass Sequenzpunkte existieren, denn wenn Sie nichts über sie wissen, können Sie einfach Code schreiben, der beim Testen gut läuft, aber eigentlich nicht definiert ist und möglicherweise fehlschlägt, wenn Sie ihn auf einem anderen Computer oder mit einem anderen Kompilieren ausführen Optionen. Insbesondere, wenn Sie beispielsweise x++
als Teil eines größeren Ausdrucks schreiben, der auch x
enthält, können Sie problemlos auf Probleme stoßen.
Ich glaube nicht, dass es notwendig ist, alle Regeln vollständig zu lernen - aber Sie müssen wissen, wann Sie die Spezifikation überprüfen müssen, oder besser - wann Sie Ihren Code neu schreiben müssen, damit Sie sich nicht darauf verlassen über Sequenzpunkte Regeln, wenn ein einfacheres Design auch funktionieren würde.
... tut nicht immer, was Sie denken, dass es tun wird. Dies kann das Debugging schmerzhaft machen. Der Grund dafür ist, dass ++ n den Wert von n abfragt, modifiziert und speichert, was vor oder nach dem Abrufen von n sein könnte. Daher ist der Wert von n_squared nach der ersten Iteration nicht klar definiert. Sequenzpunkte garantieren, dass die Teilausdrücke der Reihe nach ausgewertet werden.
Tags und Links c++ sequence-points