Turbo C ++: Warum druckt printf erwartete Werte, wenn keine Variablen an ihn übergeben werden?

7

In einem Multiple-Choice-Test wurde eine Frage gestellt: Was wird die Ausgabe des folgenden Programms sein?

%Vor%

und die Auswahlmöglichkeiten waren verschiedene Permutationen von 10, 5 und 2. Aus irgendeinem Grund funktioniert es in Turbo C ++, das wir in der Schule verwenden. Es ist jedoch nicht kompiliert mit gcc (die eine Warnung gibt, wenn -Wall aktiviert ist) oder Clam (die Wformat aktiviert hat und standardmäßig eine Warnung gibt) oder in Visual C ++. Die Ausgabe ist wie erwartet Garbage-Werte. Meine Vermutung ist, dass es etwas mit der Tatsache zu tun hat, dass entweder Turbo C ++ 16-Bit ist und auf 32-Bit Windows XP läuft, oder dass TCC furchtbar ist, wenn es um Standards geht.

    
SgrA 22.08.2013, 19:26
quelle

5 Antworten

20

Der Code hat undefiniertes Verhalten .

In Turbo C ++ passiert es einfach, dass die drei Variablen genau an den Positionen auf dem Stack liegen, an denen das fehlende Argument printf() liegt. Dies führt dazu, dass sich das undefinierte Verhalten manifestiert, indem die "korrekten" Werte gedruckt werden.

Sie können sich jedoch nicht darauf verlassen, dass dies der Fall ist. Selbst die geringste Änderung an Ihrer Build-Umgebung (z. B. verschiedene Compiler-Optionen) könnte die Dinge auf eine willkürlich unangenehme Weise zerstören.

    
NPE 22.08.2013, 19:30
quelle
4

Die Antwort hier ist, dass das Programm alles kann - das ist undefiniertes Verhalten. Laut printf() s Dokumentation (Hervorhebung von mir):

  

Standardmäßig werden die Argumente in der angegebenen Reihenfolge verwendet, wobei jedes '*' und jeder Konvertierungsspezifikator nach dem nächsten Argument fragt (und es ist ein Fehler, wenn nicht viele Argumente angegeben werden) .

Wenn Ihr Multiple-Choice-Test keine Wahl für "undefiniertes Verhalten" hat, ist dies ein fehlerhafter Test. Unter dem Einfluss von undefiniertem Verhalten ist any auf eine solche Multiple-Choice-Testfrage technisch korrekt.

    
cdhowie 22.08.2013 19:30
quelle
4

Es ist ein undefined behaviour . Es könnte also alles Mögliche sein.

Versuchen Sie

zu verwenden %Vor%

Grund: - Lokale Variablen werden im Stapel aufgerufen, und printf in Turbo C ++ sieht sie in derselben Reihenfolge, in der sie im Stapel zugewiesen wurden.

VORSCHLAG (Von Kommentaren): -

Zu verstehen, warum es sich mit einem bestimmten Compiler in einer bestimmten Weise verhält, kann bei der Diagnose von Problemen nützlich sein, aber Sie verwenden die Informationen nicht anderweitig.

    
Rahul Tripathi 22.08.2013 19:29
quelle
3

Was eigentlich passiert, ist, dass Argumente normalerweise auf dem Aufruf-Stack übergeben werden. Lokale Variablen werden auch auf dem Aufruf-Stack übergeben, und so sieht printf() diese Werte in der Reihenfolge, in der der Compiler sie gespeichert hat.

Dieses Verhalten ist ebenso wie viele andere unter dem Dach von undefined behavoir

erlaubt     
quelle
2

Nein, es hängt nicht mit der Architektur zusammen. Es hängt damit zusammen, wie TurboC ++ den Stack handhabt. Variablen a , b und c sind Einheimische und als solche in dem Stapel zugeordnet. printf erwartet auch die Werte im Stapel. Offenbar hat TurboC ++ nichts anderes zu dem Stapel hinzufügen, nachdem die Einheimischen und printf in der Lage ist, sie als Parameter zu nehmen. Nur Zufall.

    
Mario Rossi 22.08.2013 19:34
quelle