9

In this Code Golf post gibt es die Behauptung, dass, so dass diese eine wohlgeformte Linie „die zweite Variable in einer Definition immer auf 1 gesetzt ist“:Ist der zweite int in einer Mehrfachdeklaration immer auf 1 gesetzt?

int i=-1,c,o,w,b,e=b=w=o=c; 

Und angeblich alles außer i auf 1 gesetzt, weil c ist automatisch 1.

Ich dachte, ich wüsste etwas C, und dachte, das war illegal (UB und ergibt sich, wenn überhaupt in zufälligen Stapel Inhalt).

Setzt C wirklich c auf 1?

+1

ich das nicht bekommen wirklich, 'c' an den Rest der Variablen nicht initialisierten zugeordnet ist, kann ich falsch sein, aber es scheint nicht definiertes Verhalten. –

+3

Laut [this] (http://meta.codegolf.stackexchange.com/questions/5486/is-an-answer-allowed-to-use-undefined-but-consistent-behaviour) ist konsistentes undefiniertes Verhalten in Ordnung Für Code-Golfen, vielleicht hat der Schöpfer des Programms das ausgenutzt. – Downvoter

+0

Wenn 'i' automatische Speicherdauer hat, ist dies wohlgeformt. Wenn es sich um eine statische Speicherdauer handelt, ist es fehlerhaft, da zum Initialisieren der Variablen konstante Ausdrücke erforderlich sind. – Downvoter

Antwort

5

Ich bin das OP von CodeGolf. Es scheint, ich hatte einfach einen Tippfehler, ich wollte sagen int i=-1,c,o,w,b,e=b=w=o=c=1; Auf diese Weise wird der zweite definierte int immer auf 1 gesetzt und die anderen können darauf eingestellt werden. Die Verwirrung ist, dass ich ursprünglich die Variable hatte, die als nächstes kommt (L = 3) als nur l (undefiniert), und ich setzte alle anderen Variablen auf e = b = w = o = c = (L = 3); was in meinen Gedanken L auf 3 setzen würde, true dafür zurück (1), dann setze den Rest auf 1.

Ein paar Tests später stellte ich fest, dass sie nur alle auf 3 setzten und nur mit arbeiteten Die spezifische Zeichenfolge, mit der ich meinen Code getestet habe. Also löschte ich sie und änderte sie, um nur L = 3 fest codiert zu sein und die anderen e=b=w=o=c=1;L=3 zu sein. Irgendwann habe ich cmd + z zu oft gedrückt und das "=" und die "1" entfernt, so dass ich nur noch e=b=w=o=c; übrig hatte. Aufgrund der konstanten Undefiniertheit (zumindest auf meiner IDE) wurde sie immer als 0 definiert und der Fehler wurde daher nicht bemerkt.

Jetzt, wo ich es wieder korrigiert habe, dank diesem Beitrag werden die Byte-Längen gleich sind und es gab keine Notwendigkeit für irgendwelche dieser schwierigen e=b=w=o=c=1 Code sowieso, dachte ich nur die Bytelänge war anders, denn wenn ich kopieren klebte meine Funktion in einen Byte-Zähler, der zeigte, dass es 2 Bytes kleiner war (ich wusste nicht, dass ich nur einen Tippfehler hatte und 2 Bytes fehlte).

Meine IDE definiert diese Variablen immer als 0. Mein Code ist so entworfen, dass er mit allen Variablen arbeitet, die als 1 definiert sind. Die Tatsache, dass w/0 funktioniert, ist Zufall. Auch nur, weil es auf meiner IDE passiert, bedeutet es nicht, dass es auf anderen, obwohl ich es auf einigen IDEs jetzt on-line getestet habe und viele Schleifen laufen lasse und es scheint, immer Rückkehr 0. Auf jeden Fall habe ich aktualisiert meinen ursprünglichen Code, um sie auf 1 zu setzen, wie es sein sollte (das Hinzufügen von 2 Byte zu meinem Programm).

Dank für die Eingabe der jeder

+3

Mit dieser Art von Fragen erwarten Sie eine Antwort nach dem Motto "Dies ist UB, verbrennen Sie denjenigen, der diesen Code auf dem Altar von Standard-C++ geschrieben hat" oder "Dies ist ein erstaunlicher Trick, der eine dunkle Ecke von C++ enthüllt". Und dann kamst du und warst wie "Hallo Leute, also ... ja, ich habe einen CTRL-Z-Fehler gemacht ...", was ... ziemlich enttäuschend ist ... na ja. es passiert :) – bolov

5

Dieser Code zeigt undefined behavior. Die Variablen c, o, b und w sind nicht initialisiert. Das heißt, ihr Inhalt ist unbestimmt.

Aus dem Bereich 6.7.9 der C standard:

Wenn ein Objekt, das die automatische Speicherdauer hat nicht explizit initialisiert wird, ist ihr Wert unbestimmt.

Der unbestimmte Wert von c wird dann mehreren anderen Variablen zugewiesen. Durch Lesen des Werts einer nicht initialisierten Variablen ruft der Code undefiniertes Verhalten auf.

Der Anfangswert von ckönnte 1 sein, aber wenn es so ist, ist es kein vorhersagbarer Wert.

Beachten Sie auch, dass die obige Aussage sowohl Initialisierung enthält (für i und e) und Zuordnung (für c, o, b und w), so dass diese Aussage nicht in Dateigültigkeitsbereich kompiliert.

Ich habe versucht, die Funktion im verknüpften Post auszuführen, und es hat die erste Testeingabe nicht bestanden. Undefiniertes Verhalten

2

Es gibt keine solche magische Regel in der C-Norm, dass das zweite int Objekt mit 1 eingestellt werden soll. Tatsächlich ist der Wert unbestimmt, in diesem Fall ruft der Code das unbedingte UB auf.

C11 § 6.3.2.1/2 Lvalues, Arrays und Funktion Bezeich

Wenn der L-Wert ein Objekt der automatischen Speicherdauer bezeichnet, dass mit der register Speicher Klasse deklariert worden sein (nie hatte seine Adresse genommen), und das Objekt ist nicht initialisiert (nicht mit einem Initialisierer deklariert und keine Zuordnung wurde vor zu verwenden), das Verhalten ist nicht definiert.

Aber lassen Sie uns für einen kurzen Moment anders annehmen. Hier ist nur ein Beispiel Assembly, generiert für x86-64 Architektur auf GCC 6.3, ausgeschaltete Optimierung, SysV ABI Aufrufkonventionen:

mov  DWORD PTR [rbp-4], -1 
    mov  eax, DWORD PTR [rbp-8]  ; ??? 
    mov  DWORD PTR [rbp-12], eax 
    mov  eax, DWORD PTR [rbp-12] 
    mov  DWORD PTR [rbp-16], eax 
    mov  eax, DWORD PTR [rbp-16] 
    mov  DWORD PTR [rbp-20], eax 
    mov  eax, DWORD PTR [rbp-20] 
    mov  DWORD PTR [rbp-24], eax 

Soweit der Compiler betroffen ist, gibt es keine Garantien. Die Variable c befindet sich im aktuellen Stapelrahmen bei RBP-8 Offset. Sein Anfangswert ist was auch immer wurde zuvor auf Stapel gehalten.

+1

Das ist _eine_ Möglichkeit von undefiniertem Verhalten. Aber es ist undefiniert, so dass Ihr Programm abstürzen kann, oder alle Variablen auf andere Werte gesetzt werden, oder alle Variablen bleiben undefiniert mit mehr Spaß später in Ihrem Programm. – gnasher729

Verwandte Themen