visual studio compiler zählt runter bei adressenbelegungen


  • Mod

    s.sebastian schrieb:

    4-5 mal geht immer runter hmmm.

    Das Verhalten sollte auch immer gleich sein. Es ist schließlich der gleiche Code, der muss die Variablen an gleicher Stelle finden. Bloß der Offset verändert sich eventuell (ASLR*).

    Ansonsten ist es übrigens genau so normal, dass runtergezählt wird, wie dass hoch gezählt wird. Man könnte jetzt noch technische Gründe der üblichen Calling Conventions und Optimierungen anführen, wann und warum eher runter, hoch oder ganz wild gezählt wird, aber ich glaube hier sollte die Botschaft eher sein, dass die Reihenfolge und Zählweise weder festgelegt ist, noch sich von einem Normalsterblichen sicher vorhersagen lässt. Und sie sollte ohnehin nicht interessant sein. Wenn dein Code da irgendwelche Tricks macht, die bestimmte Muster ausnutzen, dann wüsstest du ohnehin, wo die Muster herkommen.

    *: Wenn du das abschaltest, sollten die Adressen übrigens immer exakt gleich sein, solange du das Programm nicht neu übersetzt.



  • hmm int ist 4 byte groß und es zählt 6 byte runter.

    danke für die zahlreichen antworten.



  • s.sebastian schrieb:

    ja das is doch nicht richtig so, dass muss doch hochzählen und nicht runter.
    das irretiert mich!

    Soweit ich das richtig in Erinnerung habe, wächst bei x86 der Stack von den hohen Adressen zu den niedrigeren. Wäre also sogar korrekt.


  • Mod

    s.sebastian schrieb:

    hmm int ist 4 byte groß und es zählt 6 byte runter.

    Wo zählst du 6? Ich zähle vor allem lauter Schreibfehler, da du wohl abgetippt hast, anstatt C&P zu nutzen. Aber eine 6 sehe ich in keiner der möglichen Kombinationen.
    Vor allem solltest du hier aber die Pointergröße sehen: Der int liegt nämlich schon von klein nach groß im Speicher. Also so

    kleinere Adressen <-    |    pn     |   n   |  -> Größere Adressen
                           &pn         &n
    

    P.S.: Bitte wähle aussagekräftige Threadtitel! Als registrierter Nutzer kannst du diese auch im Nachhinein noch ändern.
    P.P.S.: Oh, du bist s.lukas! Na, du hast dich ja anscheinend wieder beruhigt nach deinem Anfall. Trotzdem: Threadtitel!



  • Ja, Stack waechst nach unten. Wie weit Stackvariablen auseinander liegen haengt von Compiler und Debuginformationen ab.



  • Ja, der Stack wächst üblicherweise nach unten und nicht nach oben.

    C++ garantiert hier allerdings gar nix. Die Adressen könnten einfach irgendwie verteilt sein. C++ schreibt nichtmal vor dass "automatic storage" über den Stack gemacht werden muss.

    ----

    Hmmm...

    S.lukas, s.sebastian...
    Zeitnahe registrierung nach dem Ban. Gleiches Namensschema. Ähnlicher Schreibstil.

    Hmmm...


  • Mod

    hustbaer schrieb:

    S.lukas, s.sebastian...
    Zeitnahe registrierung nach dem Ban. Gleiches Namensschema. Ähnlicher Schreibstil.

    Ja, er ist das. Ich kann das sehen. Aber sofern er sich benimmt, habe ich keinen Grund, ihn nochmal zu bannen. Er scheint schließlich halbwegs gelernt zu haben, wie man sich benimmt.



  • SeppJ schrieb:

    hustbaer schrieb:

    S.lukas, s.sebastian...
    Zeitnahe registrierung nach dem Ban. Gleiches Namensschema. Ähnlicher Schreibstil.

    Ja, er ist das. Ich kann das sehen.

    Woran kannst du das sehen?



  • IP, E-Mail.



  • Zum "Runterzählen" und dem Stack im Allgemeinen gibt es einen guten Artikel bei AltDevBlogADay: http://www.altdevblogaday.com/2011/12/14/c-c-low-level-curriculum-part-3-the-stack/


  • Mod

    Das Wachstum des Stacks von oben nach unten erklärt aber noch nicht, wieso die lokalen Variablen (hier) auch von oben nach unten geordnet sind. Schließlich holt sich eine Funktion normalerweise gleich ihren ganzen Stackspeicher auf einmal (von Sondersachen wie VLAs mal abgesehen) und legt darein ihre Variablen wie sie möchte. Die Stackbereiche der einzelnen Funktionsebenen liegen dann von oben nach unten im Speicher. Die lokale Ordnung ist jedoch willkürlich (und wird bei höherer Optimierung auch total durcheinander sein).



  • Disclaimer: Diese Antwort basiert auf Glauben.

    Das Anlegen von lokalen Variablen muss nicht am Anfang der Funktion geschehen (im Gegensatz zu C). D.h. es wird nur soviel auf den Stack gepackt, wie gerade noetig. Auch vorausschauend Variablen auf den Stack zu legen, kollidiert auch mit vorzeitigen returns. Desweiteren werden beim Verlassen des Scopes die Variablen in umgekehrter Reihenfolge zerstoert, d.h. sie auf den Stack in Reihenfolge ihrer Erstellung abzulegen, ist nur logisch, da sich nicht extra eine Ordnung gemerkt werden muss. Wie weit dieses Konzept bei primitiven Typen aufgeweicht wird, kann ich aber nicht sagen.


  • Mod

    Ich glaube, da glaubst du falsch 🙂 . Die Definition nicht am Scopebeginn in C++ ermöglicht vor allem, dass man sich eventuell teure Konstruktoren und Destruktoren sparen kann. Der Speicherplatz wird sicherlich schon vorher belegt, denn es wäre ineffizient, diesen nach und nach zu holen (es ist zwar nur eine Addition, aber immerhin). Es wird auch nicht nach und nach bei der Zerstörung freigegeben, sondern alles in einem Rutsch. Es anders zu machen hätte nur Nachteile. Es werden bloß die Destruktoren rückwärts aufgerufen, dann kommt komplett das Wegräumen des belegten Stackspeichers (d.h. einfach Stackpointer versetzen und was sonst noch so beim return passiert).

    In C kann man natürlich auch Variablen mitten in der Funktion definieren, auch C kennt Scopes. Und in beiden Sprachen kann der Compiler anhand der Benutzung der Variablen entscheiden, wann sie in Verwendung ist und ob dadurch eventuell Wiederbenutzung des Gesamtstackspeichers der Funktion möglich ist. Das hat dann aber nur indirekt mit der Reihenfolge zu tun und führt bloß zu der beschriebenen wilden Anordnung bei hohen Optimierungen.



  • Also natuerlich wird der Speicherbereich vorher geholt, denn dieser ist fuer den Stack fix.



  • @SeppJ
    Ja, da hast du schon recht. Nur weil der Stack in Richtung X wächst heisst das noch lange nix.
    Wie ich auch schon geschrieben habe: der Compiler darf da machen wozu er lustig ist, garantiert ist gar nichts. Nichtmal dass hier überhaupt irgend ein Stack verwendet wird.

    Er könnte genau so malloc/free Aufrufe oder dergleichen bei jedem Eintritts-/Austrittspunkt der Funktion generieren. Wäre natürlich beknackt, aber ich wüsste keinen Grund warum es nicht erlaubt sein sollte.



  • SeppJ schrieb:

    hustbaer schrieb:

    S.lukas, s.sebastian...
    Zeitnahe registrierung nach dem Ban. Gleiches Namensschema. Ähnlicher Schreibstil.

    Ja, er ist das. Ich kann das sehen. Aber sofern er sich benimmt, habe ich keinen Grund, ihn nochmal zu bannen. Er scheint schließlich halbwegs gelernt zu haben, wie man sich benimmt.

    Hihi, OK.
    Mir solls Recht sein.


Anmelden zum Antworten