i++ != i+1 ?
-
Könnten die Compiler da keine Warnung herauswerfen?
Hier noch was zu ähnlichem:
http://forum.fachinformatiker.de/net/111861-i-i-i.html
http://archiv.raid-rush.ws/t-498122.htmlMfG f.-th.
-
Leute, jetzt müsst ihr mir auch mal helfen
Ich schreibe meine for-Schleife so:
for (int i=0; i<100; i++) {}
Was ist denn jetzt der Unterschied, wenn man statt "i++" einfach "++i" schreibt? Ist das das selbe oder gibt es auch dafür eine Erklärung?
Danke schonmal im Voraus.
-
Minispiri schrieb:
Leute, jetzt müsst ihr mir auch mal helfen
Ich schreibe meine for-Schleife so:
for (int i=0; i<100; i++) {}
Was ist denn jetzt der Unterschied, wenn man statt "i++" einfach "++i" schreibt? Ist das das selbe oder gibt es auch dafür eine Erklärung?
Danke schonmal im Voraus.
Führ mal das Programm aus!
int main() { int i = 7; cout << i << endl; cout << i++ << endl; cout << ++i << endl; }
Ops C - Forum, denkt euch die printf- Funktion
-
Zeus schrieb:
Führ mal das Programm aus!
Hab ich gerade getan.
Also bei mir hat sich mit diesem Code nichts geändert.
D.h. Frage beantwortet, Danke
-
Minispiri schrieb:
Zeus schrieb:
Führ mal das Programm aus!
Hab ich gerade getan.
Also bei mir hat sich mit diesem Code nichts geändert.
D.h. Frage beantwortet, Danke
Weil die Kopf der For Schleife aus Drei Teilanweisung besteht, kann es dort nicht missintepretiert werden, dort ist dann Enscheident ob die Variable vom Klassen sind, dann könnte es teuer werden, ops das ist aber C++^^
-
Minispiri schrieb:
Ich schreibe meine for-Schleife so:
for (int i=0; i<100; i++) {}
Was ist denn jetzt der Unterschied, wenn man statt "i++" einfach "++i" schreibt? Ist das das selbe oder gibt es auch dafür eine Erklärung?
Ist in diesem Fall gleichwertig. Weil der Wert des Ausdrucks
i++
hier nicht verwendet wird.
-
mngbd schrieb:
Minispiri schrieb:
Ich schreibe meine for-Schleife so:
for (int i=0; i<100; i++) {}
Ist in diesem Fall gleichwertig. Weil der Wert des Ausdrucks
i++
hier nicht verwendet wird.Soso, der Ausdruck wird also nicht verwendet. Und was passiert beim nächsten Anlauf des Abbruchsbedingungstest? Hier wird der Ausdruck sehr wohl wiederverwendet und deshalb macht es Sinn, auch hier ++i zu verwenden um dem Compiler zu schnellerem Code zu animieren, wenn er es nicht schon selbst bemerkt.
-
Wutz schrieb:
Und was passiert beim nächsten Anlauf des Abbruchsbedingungstest?
Das würde mich jetzt aber interessieren.
-
Wutz schrieb:
auch hier ++i zu verwenden um dem Compiler zu schnellerem Code zu animieren, wenn er es nicht schon selbst bemerkt.
i++ vs ++i in einem for würde ich als gleichwertig betrachten... glaub kaum, dass da eins schneller ist. müsste man mal bei den entsprechenden gcc entwickler(n) anfragen. beim vc++ kannst ja mal den support anfragen ob sie details rausrücken
-
Wutz schrieb:
... und deshalb macht es Sinn, auch hier ++i zu verwenden um dem Compiler zu schnellerem Code zu animieren, wenn er es nicht schon selbst bemerkt.
Nenn mir einen Compiler (Release- oder Debug-Build) der diesen Quatsch, den Du hier schreibst, macht.
i++, Index erhöhen und fertig!
-
Die Assembler-Leute können dies sicher besser erklären, aber ohne dass der Compiler hier optimierend eingreift, steht nach dem Prefixinkrement der Wert schon vorgeladen im Register und somit benötigt die UNMITTELBAR folgende Anweisung, wenn sie den Wert benötigt, kein Laden (ins Register) mehr, was beim Postfix nicht gegeben ist, da hier die letzte Anweisung ein inc ist (sein sollte).
Das Prefix ist als Compiler-Hint zu verstehen, ohne Garantie, dass der Compiler dies auch entsprechend umsetzt.
-
Die Assembler-Leute werden nutzlose Statements erst gar nicht in ihr Listing übernehmen. Und genauso wird sich auch jeder halbwegs gescheite Compiler verhalten.
-
bin zwar kein gcc developer, hab mich aber aus spaß letzten monat bischen durch den code gewühlt... so schauts da aus:
/* Unroll LOOP for that we are able to count number of iterations in runtime LOOP->LPT_DECISION.TIMES + 1 times. The transformation does this (with some extra care for case n < 0): for (i = 0; i < n; i++) body; ==> i = 0; mod = n % 4; switch (mod) { case 3: body; i++; case 2: body; i++; case 1: body; i++; case 0: ; } while (i < n) { body; i++; body; i++; body; i++; body; i++; } */
faktisch können wir uns jetzt immernoch draüber streiten ob jetzt i++ oder ++i schneller ist
-
bzw. geben die sich den akt so einen "specialcase" zu optimieren und scheitern dann an nem simplen i++
eher unwahrscheinlich
-
"Die" scheitern vielleicht nicht, aber es gibt einige alte Compiler für ausgefallene Plattformen, die i++ folgendermassen implementieren:
int i_new = i+1; <ausdruck mit i> // hier weggelassen i = i_new;
Und schon sinds zwei Anweisungen.
++i hingegen ist garantiert nur eine.
Diese Richtlinie stammt aber noch aus der Urzeit und ich glaube nicht, dass diesbezüglich noch irgendwelche Vorkehrungsmassnahmen getroffen werden müssen.
Viel Code benutzt aber die Postfix-Variante, so dass es sich eingebürgert hat, diese zu verwenden.Die von dir gezeigte Transformation macht mir aber Angst. Im Wissen, dass ein Fall zwar in der Praxis nie mehr als einmal auftritt, in der Theorie aber mit einer Schleife, die maximal ein mal durchlaufen wird, oft keinmal, bewältigen lässt, wähle ich natürlich eine Schleife.
Der gcc macht ein Riesenblock draus, obwohl das in diesem Falle eine Performanzbremse ist.
-
Minispiri schrieb:
Leute, jetzt müsst ihr mir auch mal helfen
Ich schreibe meine for-Schleife so:
for (int i=0; i<100; i++) {}
Was ist denn jetzt der Unterschied, wenn man statt "i++" einfach "++i" schreibt? Ist das das selbe oder gibt es auch dafür eine Erklärung?
Danke schonmal im Voraus.
Ist in dem Fall egal, weil ++i oder i++ *immer* nach Ausführung des Schleifenkörpers duchgeführt wird. Dazwischen kann sich nichts einmogeln. Wegen des Nachhers mag ich aber die Schreibweise ++i nicht, aber eigentlich ist's Banane.
-
Wutz schrieb:
mngbd schrieb:
Minispiri schrieb:
Ich schreibe meine for-Schleife so:
for (int i=0; i<100; i++) {}
Ist in diesem Fall gleichwertig. Weil der Wert des Ausdrucks
i++
hier nicht verwendet wird.Soso, der Ausdruck wird also nicht verwendet. Und was passiert beim nächsten Anlauf des Abbruchsbedingungstest? Hier wird der Ausdruck sehr wohl wiederverwendet und deshalb macht es Sinn, auch hier ++i zu verwenden um dem Compiler zu schnellerem Code zu animieren, wenn er es nicht schon selbst bemerkt.
Ich meinte: semantisch gleichwertig. Auch hab ich nicht behauptet, dass der Ausdruck nicht "verwendet" wird, weil ich keine Ahnung habe, was das heissen soll. Es ist aber so, dass der Wert des Ausdruckes nach der Evaluierung verworfen wird, der Ausdruck (der auch eine Anweisung ist) also alleine wegen seines Seiteneffektes dort steht.
Was den Rest angeht, ist fricky's Argument gültig:
a = i++; // mache man zu a = i; i += 1; // und a = ++i; // mache man zu i += 1; a = i;
Aus Sicht der Sprache ist keines von beiden schneller, und alles andere ist system- oder compilernahes Kauderwelsch.