Ist die Ausgabe von printf ("%d %d", c++, c); auch undefiniert?
Kurzem stieß ich auf ein post Was ist die richtige Antwort für cout << c++ << c;? und Frage mich, ob die Ausgabe von
int c = 0;
printf ("%d %d", c++, c);
ist auch undefiniert??
Studierte ich in Vorträgen, dass die post-fix-und Präfix-Operatoren-Inkrement-Wert erst nach dem aufstehen ein Semikolon. So nach mir, die Ausgabe 0 0
ist richtig!!!!!!
- mögliche Duplikate von mehrere '++' arbeiten mit Variablen und Zeiger
Du musst angemeldet sein, um einen Kommentar abzugeben.
Senden Sie Ihre Dozentin /Ihr Dozent zu mir, so dass ich
nehmen Sie sich einen Baseballschläger, um ihnhöflich auf seine Fehler.Wann genau die Nebenwirkung, die entweder pre - oder postfix
++
und--
angewendet wird, ist unbekannter, abgesehen von der Voraussetzung, dass es passieren wird, bevor die nächste Sequenz zeigen. In einem Ausdruck wiea
aktualisiert werden können sofort nacha++
bewertet wurde, oder das update kann aufgeschoben werden, bisa++ * b
wurde ausgewertet und das Ergebnis zugewiesenx
, oder irgendwo dazwischen.Dies ist der Grund, warum Ausdrücke wie
i++ * i++
undprintf("%d %d", c++, c)
unda[i++] = i
und eine Vielzahl von anderen sind alle schlecht juju. Erhalten Sie unterschiedliche Ergebnisse auf der Basis der compiler-Optimierung Einstellungen, die umliegenden code, etc. Der Sprache standard explizit lässt sich das Verhalten undefined, so dass der compiler nicht verpflichtet ist, "das richtige tun", was auch immer die richtige sein mag. Denken Sie daran, die definition für Undefiniertes Verhalten istDies ist eine bewusste design-Entscheidung - die Begründung für das verlassen der Reihenfolge dieser Operationen nicht spezifiziert ist, zu geben, die Umsetzung der Freiheit ordnen Sie die Bewertung, um zu Optimierungszwecken. Allerdings, im Austausch für diese Freiheit, bestimmte Vorgänge nicht genau definierte Ergebnisse.
Beachten Sie, dass ein compiler ist frei, um versuchen zu erkennen, diese Fällen und Ausgabe einer Diagnose;
printf("%d %d", c++, c);
wäre leicht genug zu fangen, aber das wäre ein narzist zu erkennen, im Allgemeinen Fall. Stell dir vor, die geschrieben worden warprintf("%d %d", (*p)++, c)
; wennp
Punkte zuc
, dann ist das Verhalten undefiniert, sonst ist es okay. Wennp
zugeordnet ist, in einer anderen übersetzungseinheit, dann gibt es keine Möglichkeit zu wissen, zur compile-Zeit, ob das ein problem ist oder nicht.Dieses Konzept ist nicht schwer zu verstehen, dennoch ist es eines der am konsequentesten falsch verstanden (und mis-gelehrt) Aspekte der C-Sprache. Kein Zweifel, dies ist der Grund, warum die Java-und C# - Sprache-Spezifikationen zwingen, eine spezifische Evaluierung, um für alles (alle Operanden werden ausgewertet, von Links nach rechts, und alle Nebenwirkungen, die sofort angewendet werden).
Dies ist nicht, wie der standard es beschreibt. Ein Reihenfolge Punkt ist eine Stelle im code, die Nebenwirkungen, die aufgetreten sind, die in vorherigen teilen des Codes ausgewertet wurden. Das Komma zwischen den Argumenten einer Funktion ist nicht eine Sequenz Punkt, so ist das Verhalten undefiniert.
Die Reihenfolge der Auswertung der Funktionsargumente nicht spezifiziert. Es gibt keine Garantie, dass die Argumente einer Funktion werden in der Reihenfolge ausgewertet
(1, 2, N)
, so gibt es keine Garantie, dass das Inkrement wird ausgewertet, bevor das zweite argument übergeben wird.Nein, das Verhalten ist undefiniert, so dass Sie kann nicht vernünftigerweise behaupten, dass die Ausgabe 0 ist 0.
c
in der gleichen Reihenfolge zeigenDas Verhalten des Programms ist undefiniert, da es gegen die Anforderungen von 6,5 Ausdrücke:
c++
undc
sind beide bewertet, ohne eine dazwischenliegende Sequenz Punkt, und der Vorherige Wert vonc
ist Lesen zu bestimmen, wird der Wert gespeichert werden, indemc++
, und bestimmen Sie den Wert des Ausdrucksc
.Ist das Verhalten auf jeden Fall undefiniert, aufgrund der undefinierten Bewertung Reihenfolge der Parameter. Können Sie belegen, dass dieses "undefined Ausgabe" dabei einige Stichproben:
c
für das Lesen der Vorherige Wert sowie für die Aktualisierung zur gleichen Zeit in der gleichen Reihenfolge zeigen. Tests wie diese nicht wirklich beweisen, es ist undefiniert, nur Lesen den standard kann man sagen.Du hast Recht: es ist nicht definiert. Der Grund dafür ist, dass, obwohl es garantiert ist, dass die drei Argumente für
printf()
werden ausgewertet, bevorprintf()
heißt, die Reihenfolge, in der die drei Argumente ausgewertet werden, nicht definiert ist.Es technisch falsch ist, dass die Inkrementierung erfolgt nur, nach dem Semikolon, übrigens. Was der standard garantiert, dass die Schrittweite wird auftreten, nicht später als das Semikolon. [Tatsächlich, in Ihrem Fall glaube ich, dass der standard garantiert, dass es auftreten wird, bevor die Steuerung an die
printf()
Funktion-aber jetzt ist diese Antwort ab zu spin-off in Bereiche der pedantischen trivia, also lassen Sie mich lassen Sie die Sache ruhen dort!]Sowieso, kurz, Sie sind Recht. Das Verhalten ist undefiniert.
Update: Wie @R.. zu Recht feststellt, die zu undefiniertem Verhalten kommt aus dem Mangel an eine Sequenz zwischen Argumenten. Der standard ist sehr vorsichtig in Bezug auf die Partizipien unbekannter und undefined so ist die Korrektur akzeptiert, mit Dank.
C
.Dieses Programm weist eine Kombination der beiden unspezifische Verhalten und Undefiniertes Verhalten. Beginnend mit der unspezifisch Verhalten, die Entwurf der C99-standard in Abschnitt
6.5
Absatz3
sagt:Er sagt auch, außer wie angegeben später und speziell zitiert
function-call ()
, so sehen wir, dass später auf den Norm-Entwurf in Abschnitt6.5.2.2
Funktionsaufrufe Absatz10
sagt:So dass wir nicht wissen, ob das Lesen von C oder die Auswertung von C++ geschieht zuerst in dieser code-Zeile:
darüber hinaus in Abschnitt
6.5.2.4
Postfix-Inkrement-und Dekrement-Operatoren Absatz2
sagt:Also alles, was wir wissen, ist, dass bei der Durchführung der post-Inkrement -
c
aktualisiert werden, nachdem Ihr Wert ist gelesen, aber bevor der nächste Reihenfolge Punkt, was Recht ist vorprintf
genannt wird, aber sonst nichts. Für die Undefiniertes Verhalten, wenn wir uns an Abschnitt6.5
Absatz2
aus dem Norm-Entwurf, sagt:In der
printf
Ausdruckc
s vor der Wert gelesen wird, um zu bewerten, sowohl C++ und C und so jetzt sind wir in undefined Gebiet.