Frage

Ich bin mit Coverity Prevent an einem Projekt Fehler zu finden.

Es gibt einen Fehler für diesen Ausdruck (Die Variablennamen sind natürlich geändert):

x=
   (a>= b) ?
   ++x: 0;

Die Botschaft lautet:

  

EVALUATION_ORDER Defekt: In „x=(a>= b) ? ++x: 0;“, „x“ wird in „x“ (die Zuordnung LHS) und geschrieben in „(a>= b) ? ++x: 0;“ geschrieben, aber die Reihenfolge, in der die Nebenwirkungen stattfinden, nicht definiert ist, da es kein intervenierende Sequenz Punkt . END OF MESSAGE

Während ich diese „x = x++“ verstehen kann nicht definiert ist, ist dies ein etwas schwieriger für mich. Ist das eine falsch positiv oder nicht?

War es hilfreich?

Lösung

Konditionaloperator ?: hat eine Sequenz Punkt zwischen Auswertung der Bedingung (erster Operand) und Auswertung der zweiten oder dritten Operanden, aber es hat keine spezielle Sequenzpunkt nach Die Bewertung der zweiten oder dritten Operanden. Das bedeutet, dass zwei Modifikationen von x in diesem Beispiel sind potentiell in Konflikt (nicht durch eine Sequenz Punkt getrennt). Also, Coverity Prevent ist richtig.

Ihre Aussage in dieser Hinsicht ist praktisch gleichbedeutend mit

a >= b ? x = ++x : x = 0;

mit dem gleichen Problem wie in x = ++x.

Nun scheint der Titel Ihrer Frage darauf, dass Sie nicht wissen, ob x = ++x nicht definiert ist. Es ist in der Tat nicht definiert. Es ist nicht definiert, für den gleichen Grund x = x++ nicht definiert ist. Kurz gesagt, ist, wenn das gleiche Objekt geändert mehr als einmal zwischen einem Paar von benachbarten Sequenzpunkten wird das Verhalten undefiniert. eine Sequenz gibt es keine Stelle auf „Isolat“ Diese Modifikationen voneinander in diesem Fall x wird durch Zuordnung und durch ++ modifiziert. So ist das Verhalten nicht definiert. Es gibt absolut keinen Unterschied zwischen ++x und x++ in dieser Hinsicht.

Andere Tipps

Unabhängig von der Richtigkeit der Nachricht, den Code in Frage x= (a>= b) ? x+1: 0; ersetzen erreicht das gleiche Ziel ohne Verwirrung. Wenn das Werkzeug verwechselt wird dann vielleicht die nächste Person zu betrachten dieser Code sein.

Dies funktioniert das x nicht davon ausgehen, eine überladene Inkrementoperator mit Nebenwirkungen hat, dass Sie hier verlassen.

Die Anweisung x = ++x; schreibt an die Variable x zweimal, bevor man die Sequenzpunkt und damit die Verhalten ist nicht definiert.

Es ist schwer, einen Compiler produziert Code für "x = ++ x;" vorstellen, die in der Tat nicht die gleiche Arbeit wie „++ x“. Wenn x nicht flüchtig ist, wäre es jedoch legal für einen Compiler die Anweisung zu verarbeiten „y = ++ x;“ wie

  y=x+1;
  x=x+1;

Die Aussage "x = ++ x;" würde somit werden

  x=x+1;
  x=x+1;

, um das Ziel eines ein arithmetischer Zuweisungsausdruck gewöhnen zu schnell als Quelle Wenn mit Operanden für einen anderen würde eine Pipeline-Verzögerung verursachen könnte die frühere Optimierung sinnvoll sein. Offensichtlich fatal, wenn der erhöhte und zugeordneten Variablen sind ein und dasselbe.

Wenn der Variable ‚x‘ flüchtig ist, kann ich glaube nicht, jede Codesequenz in dem ein Compiler, der nicht absichtlich versucht, gemein zu sein legitim betrachten könnte „x = x ++;“ wie jede andere Wirkung, die alle Teile von ‚x‘ genau einmal und Schreiben der gleichen korrekten Wert in alle Teile der ‚x‘ genau zweimal als das Lesen.

ich, dass logisch annehmen, wenn Sie entweder schreiben „x = ++ x“ oder „x = x ++“, so oder so würden Sie das Endergebnis erwarten, dass x zu sein, ist eine mehr als es begann, wie. Aber es muss nur ein Schatten komplizierter. Was passiert, wenn Sie schrieb "x = x + (++ x)"? Ist dies das gleiche wie "x = x + (x + 1)"? Oder tun fügen wir eine erste und fügen Sie dann x an sich selbst, das heißt "x = (x + 1) + (x + 1)"? Was passiert, wenn wir "x = (x -) + (x ++)" geschrieben?

Auch wenn Sie eine Sprache spec schreiben könnte, die eindeutige Bedeutung dieser Art von Konstrukten gab, und konnte es dann sauber implementieren, warum würden Sie wollen? Setzen eines unären Schritt in einer Zuordnung zu derselben Variablen macht einfach keinen Sinn, und selbst wenn wir Sinn aus ihm heraus gezwungen, bietet es keine nützliche Funktionalität. Wie, ich bin sicher, könnten wir eine Compilers schreiben, die aus einem Ausdruck wie „x + 1 = y-1“ und Figur nehmen würden, dass das wirklich bedeutet „x = y-2“, aber warum die Mühe? Es gibt keinen Gewinn.

Auch wenn wir Compiler geschrieben, dass etwas getan vorhersehbar mit „x = x ++ - ++ x“, würden Programmierer müssen wissen, und die Regeln zu verstehen. Ohne offensichtlichen Vorteil wäre es nur die Komplexität Programme für zwecklos hinzuzufügen.

Um dies zu verstehen, müssen Sie ein grundlegendes Verständnis der Sequenzpunkte haben. Siehe diesen Link: http://en.wikipedia.org/wiki/Sequence_point

Für den Operator = gibt es keinen Sequenzpunkt, so dass es keine Garantie dafür gibt, dass der Wert von x geändert werden, bevor es wieder auf x zugeordnet ist.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top