Warum habe ich ++; ich–; direkt hintereinander?

Lesezeit: 5 Minuten

Benutzeravatar von DDiamond
DDiamant

Ich habe mir den Quellcode angesehen nmap das wurde 1997 veröffentlicht und mir ist dieser Codeabschnitt aufgefallen, der mir etwas seltsam vorkommt:

int i=0, j=0,start,end;
char *expr = strdup(origexpr);
ports = safe_malloc(65536 * sizeof(short));
i++;                                         /* <<<<<< */
i--;                                         /* <<<<<< */
for(;j < exlen; j++) 
  if (expr[j] != ' ') expr[i++] = expr[j]; 
expr[i] = '\0';

Warum hättest du i++; und dann i--; direkt hintereinander? i ist 0dann i++ wendet sich i zu 1. Danach, i-- wendet sich i zu 0.

Link zum ursprünglichen Quellcode. Suchen nach:

i++;
i--;

Kann jemand erklären, wofür das ist?

  • Fragen der Autor.

    – DaBler

    28. März 2020 um 14:40 Uhr

  • Ich würde vermuten, dass sie Teil eines experimentellen oder Debugging-Codes waren, den der Autor später zu entfernen vergaß.

    – Nate Eldredge

    28. März 2020 um 14:48 Uhr

  • Der Grund ist offensichtlich, Sie zu verwirren, das ist der einzige Zweck 🙂 Es besteht eine kleine Chance, dass dies einen Compiler-Fehler in einem alten Compiler umgeht, in diesem Fall hätte es einen Kommentar geben müssen, der uns diesen Grund mitteilt.

    – gnasher729

    28. März 2020 um 14:58 Uhr

  • @RingØ: Zum Spaß habe ich es mit gcc 1.27, circa 1988, auf Godbolt versucht: godbolt.org/z/yYyFrQ. (Es funktioniert nicht mit modernen Systemheadern, also musste ich alle Standardbibliotheksfunktionen selbst deklarieren.) Aber mit -O es optimiert tatsächlich diese Aussagen.

    – Nate Eldredge

    28. März 2020 um 14:59 Uhr

  • Es bedeutet, dass der Programmierer pro Zeile bezahlt wurde …

    – TonyK

    30. März 2020 um 11:59 Uhr

Benutzeravatar von dbush
dbusch

Das war ein Fehler. Diese Linien ergeben zusammen i unverändert, also hätten sie nicht dort sein sollen.

Der verlinkte Artikel, der nmap vorstellte, wurde am 1. September 1997 veröffentlicht. Schaut man sich das SVN-Repository für nmap an https://svn.nmap.org/nmapenthält die ursprüngliche Revision, die am 10. Februar 1998 eingecheckt wurde, diese Zeilen nicht:

int i=0, j=0,start,end;
char *expr = strdup(origexpr);
char *mem = expr;

ports = safe_malloc(65536 * sizeof(short));
for(;j < exlen; j++) 
  if (expr[j] != ' ') expr[i++] = expr[j]; 
expr[i] = '\0';

Dies ist also etwas, das der Autor zwischen der Veröffentlichung des ursprünglichen nmap-Quellcodes und dem ersten Einchecken in SVN gefunden und behoben hat.

  • Hmm, die Seite fehlt <pre> auch Tags um den Artikel herum; Der Inspektor von Chrome verrät, wie das zu einigen Dokumentenverstümmelungen während der DOM-Erstellung führt 😉

    – Asteroiden mit Flügeln

    29. März 2020 um 1:37 Uhr

  • Es verwirrt die Leser, was völlig unbeabsichtigt ist. Ich würde sagen, es ist eindeutig ein Bug. 😉

    – sergut

    30. März 2020 um 11:30 Uhr

  • @sergut Wikipedia stimmt dir aber nicht zu diesen Blogbeitrag geht, und ich neige auch dazu 🙂

    – Toivo Säwen

    30. März 2020 um 12:44 Uhr

  • Wenn jetzt i kein int, sondern eine ausgefallene Klasse mit Operatorüberladungen war, ist es möglich (obwohl unwahrscheinlich und im Allgemeinen ein Zeichen für schlechte Programmierpraktiken), dass dies einige Nebenwirkungen haben könnte. (Gilt natürlich nur, wenn es sich um C++ handelt.)

    – Darrel Hoffmann

    30. März 2020 um 18:12 Uhr

  • Vielleicht ist es erwähnenswert, dass in einigen Kontexten (memory-mapped IO) das Ändern einer Variablen externe Auswirkungen haben kann.

    – nullromo

    30. März 2020 um 18:17 Uhr

Benutzeravatar von SS Anne
SS Anne

Es ist nutzlos. Es bringt absolut nichts.

Wenn ich spekulieren sollte, handelt es sich wahrscheinlich um die Überreste von Debugging-Code, der während der Entwicklung verwendet wurde.

Ich vermute, dass entweder einer von i++ oder i-- wurde in einer Änderung eingeführt und die andere wurde in einer anderen eingeführt.

Ich habe jedoch keine Möglichkeit, den Einführungspunkt zu finden, da es zwischen der ursprünglichen Quellversion und der ersten SVN-Revision keine Revisionshistorie gab.

  • Ich denke, die Spekulationen über das Debuggen von Code sind zutreffend. Ich habe so viele verschiedene Arten von Debugging-Code gesehen, nur um Breakpoints dort zu bekommen, wo man sie erwartet.

    – Nathan Goings

    30. März 2020 um 16:24 Uhr

Für einen nicht optimierenden Compiler oder einen Compiler, der Hardwarenebenwirkungen erkannt hat, ist das i++; i–sequence würde dazu führen, dass i aus dem Speicher gelesen und dann neu geschrieben wird, unabhängig vom Pfad, der durch die for-Schleife und das verschachtelte if genommen wird.

Bei der parallelen Verarbeitung werden manchmal Compiler-Hacks durchgeführt, um sicherzustellen, dass eine Codesequenz ihre eigenen lokalen Kopien von Variablen anstelle von globalen Kopien verwendet.

Da es sich bei dem Beispiel um einen Codeschnipsel handelt, kann man weder den verwendeten Compiler, das erwartete Betriebssystem/Hardware, noch ob es sich um eine Codesequenz/Funktion handelt, die als eigenständiger Thread ausgeführt werden kann, feststellen.

In einfacheren Systemen habe ich vorübergehend Änderungen an Variablen erzwungen, um die Trap-Funktion in einer Debugging-Umgebung auszuführen. In diesem Fall hat der Autor möglicherweise vergessen, den Code nach Abschluss der Entwicklung zu entfernen.

  • Warum deklarieren Sie es dann nicht einfach als flüchtig?

    – vsz

    31. März 2020 um 4:56 Uhr

  • Die Erklärung von i als lokale Variable wird im obigen Code gezeigt, und es gibt keine Möglichkeit, dass ein anderer Thread an der Stelle darauf zugreift, an der die i++; i-- Linien sind.

    – zwischenjay

    31. März 2020 um 7:17 Uhr

  • @vsz Ich denke eher, er meint i wird gezwungen, nichtflüchtig zu sein. Ich habe mich jedoch nicht mit Threading in C oder C++ befasst, daher habe ich keine Ahnung, wie es als flüchtig behandelt werden könnte und wie i++; i-- würde das unterdrücken.

    – Jegor Hans

    6. April 2020 um 14:49 Uhr

  • volatile hat neben der Thread-Sicherheit noch andere Zwecke. Es kann auch beim Debuggen verwendet werden, um sicherzustellen, dass der Compiler es nicht wegoptimiert.

    – vsz

    6. April 2020 um 16:37 Uhr

Benutzeravatar von TripleM
TripleM

Ich empfehle Ihnen, nur den aktualisierten Code zu überprüfen. Wenn Sie (i = 2+1) direkt danach (i-1) verwenden, macht das keinen Sinn. Der Wert von i bleibt unverändert. Sie können es mit jedem c- oder c++-Compiler versuchen. oder sogar in jeder anderen Sprache ist es dasselbe. Führen Sie den Code im Compiler aus.

1424890cookie-checkWarum habe ich ++; ich–; direkt hintereinander?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy