Das verwirrende char in C/C++



  • Eines interessiert mich jetzt aber doch noch. Wie soll alloca() funktionieren?

    Folgendes:
    1. Die Rücksprungadresse von alloca() sowie der Integer wird auf den Stack gelegt und der Stack-Pointer inkrementiert.
    2. alloca() legt den Wert des Stack-Pointers oder den Wert des Stack-Pointers minus 8 oder ähnliches irgendwo bei der Rückgabe ab.
    3. alloca() kehrt zurück und der Stackpointer wird wieder dekrementiert.
    4. Der Rückgabewert wird in die Variable kopiert.
    5. Der Stack-Pointer muss inkrementiert werden, damit er hinter den allozierten Stack-Speicher zeigt, aber wie? Das könnte höchstens durch eine Calling-Convention gehen, bei der die Rücksprungadresse in einem Register liegt und alloca() daher selbst den Stack-Speicher inkrementieren kann, so dass dieser nur bis zum endgültigen Wert wieder dekrementiert wird.
    6. Wer sagt dem Programm, dass hier mehr Stack-Speicher alloziert wurde und der Stack-Pointer weiter dekrementiert werden muss als gedacht??



  • It's magic! delete[] kennt auch die größe vom array...



  • da magican! schrieb:

    It's magic! delete[] kennt auch die größe vom array...

    Da kann es aber Konvention sein, dass new[] die Größe des Arrays in die vier Bytes vor dem Speicher schreibt.



  • wxSkip schrieb:

    Eines interessiert mich jetzt aber doch noch. Wie soll alloca() funktionieren?

    intrinsic.

    alloca ist afaik nur ein anderer name für __builtin_alloca und das sagt ja schon alles 😉



  • Aha... Compiler-Magik hatte ich schon erwartet 😉 .



  • Also für mich sind Lambdas ja heiß aufgekochter Syntaxzucker und damit Syntaxkaramel!
    Ps: Also ich stelle mir die NAMEN der Arrays immer als Zeiger vor, bei denen der Compiler noch ein gewisses Zugriffsschema mitschleift, eben wie bei ganz normalen typisierten Zeigern auch.


  • Administrator

    #include <iostream>
    
    bool isAnArrayAPointer()
    {
      return sizeof(int[10]) == sizeof(void*);
    }
    
    bool isTheNameOfAnArrayAPointer()
    {
      int temp[10];
      return sizeof(temp) == sizeof(void*);
    }
    
    int main()
    {
      std::cout << std::boolalpha << isAnArrayAPointer() << std::endl;
      std::cout << std::boolalpha << isTheNameOfAnArrayAPointer() << std::endl;
    }
    

    Frage beantwortet? 😉

    Grüssli



  • Das weiß ich nicht, kommt auf die Frage an! Welche Frage meinst du?


  • Administrator

    Decimad schrieb:

    Das weiß ich nicht, kommt auf die Frage an! Welche Frage meinst du?

    Lies die Funktionsnamen.

    Grüssli



  • Boah, ich hab jetzt echt keine Lust hier groß auszuholen, warum ich mir das so vorstelle. Mir reicht jetzt hier zu betonen, dass eine Vorstellung nicht der Wirklichkeit entsprechen muss.



  • Irgendwo hier im Forum hatte ich zu einem ähnlichen Thema gelesen, dass ein Byte auf unterschiedlichen Maschinen nicht gleich groß sein soll.

    Wie auch immer, man könnte coden:

    char Weihnachtskalender[24]
    

    irritierenderweise könnte man aber auch coden:

    char *Weihnachskalender[24]
    

    Das ist beides nicht das gleiche, das erste eher ein der Weihnchtskalender selbst (vorerst eine Bastelarbeit, noch keine Schokolade drin 😞 ) - das letztere gleicht eher dem Kind, welches auf den Kalender guckt, und sieht: Ah, heut ist der 22. also mach ich Tür 22 auf - nur das es im Moment noch schläft, und noch gar nicht weiß, was für ein Tag heute ist...;)

    ...hm und um die Verwirrung noch etwas anzuheizen, könnte man ja meinen, der Kalender selber heisst i++ ...und nicht etwa ++*gierigegrabbelhand - dann eher vielleicht ++*datum 🤡

    http://www.c-plusplus.net/forum/276143



  • Das Hauptptoblem hier ist doch wie Dravere schon gezeigt hat, das aneinander vorbei geredet wird. Ein Array ist ein Array und ein Pointer ist ein Pointer. Aber ein Array kann durch Pointersyntax angesprochen werden, das ist doch alles...



  • Dravere schrieb:

    #include <iostream>
    
    bool isAnArrayAPointer()
    {
      return sizeof(int[10]) == sizeof(void*);
    }
    
    bool isTheNameOfAnArrayAPointer()
    {
      int temp[10];
      return sizeof(temp) == sizeof(void*);
    }
    
    int main()
    {
      std::cout << std::boolalpha << isAnArrayAPointer() << std::endl;
      std::cout << std::boolalpha << isTheNameOfAnArrayAPointer() << std::endl;
    }
    

    Frage beantwortet? 😉

    Grüssli

    Das macht doch 0 Sinn, mein Pointer verbraucht doch nicht mehr Speicher wenn er auf eine größere Datenstruktur zeigt, insofern trägt der Vergleich ob sizeof(array) == sizeof(pointer) Null zur Diskussion bei, egal welcher Meinung man auch sein mag.



  • gastantwort schrieb:

    Das macht doch 0 Sinn, mein Pointer verbraucht doch nicht mehr Speicher wenn er auf eine größere Datenstruktur zeigt, insofern trägt der Vergleich ob sizeof(array) == sizeof(pointer) Null zur Diskussion bei, egal welcher Meinung man auch sein mag.

    Es zeigt den Unterschied Array <-> Zeiger.
    Und das ein Array eben kein Zeiger ist.

    Beide Vergleiche sind btw unwahr.

    PS:
    Es geht hier nicht um Meinung. Dass ein Array kein Zeiger ist, ist einfach ein Fakt.



  • Shade Of Mine schrieb:

    Es zeigt den Unterschied Array <-> Zeiger.
    Und das ein Array eben kein Zeiger ist.

    Es zeigt eigentlich nur, dass es nicht exakt das gleiche ist. Dass der Unterschied fundamental und nicht nur eine willkürliche Definition ist zeigt es nicht. Mich würde man so jedenfalls nicht überzeugen können.



  • Bashar schrieb:

    Es zeigt eigentlich nur, dass es nicht exakt das gleiche ist. Dass der Unterschied fundamental und nicht nur eine willkürliche Definition ist zeigt es nicht. Mich würde man so jedenfalls nicht überzeugen können.

    Was würde für dich einen fundamentalen Unterschied bedeuten?



  • Warum sollte ein Array ein Zeiger sein? Da könnte auch eine Klasse ein Zeiger sein. Oder eine Referenz eine Klasse. :xmas2:



  • wxSkip schrieb:

    Eines interessiert mich jetzt aber doch noch. Wie soll alloca() funktionieren?

    Anhand der angeforderten Speichergröße wird der Platzbedarf auf dem Stack ermittelt, der Stackpointer entsprechend abgeändert und die Adresse auf dem Stack für den angeforderten Block übergeben.

    Exakt das gleiche passiert bei einem Array. Der einzige Vorteil bei einem Array ist, daß der Compiler weiß wie groß es ist. Das war's dann aber auch schon an Unterschieden.



  • huüh schrieb:

    Da könnte auch eine Klasse ein Zeiger sein.

    Eine Iterator-Klasse ist eine Abstraktion eines Zeigers.



  • ~john schrieb:

    wxSkip schrieb:

    Eines interessiert mich jetzt aber doch noch. Wie soll alloca() funktionieren?

    Anhand der angeforderten Speichergröße wird der Platzbedarf auf dem Stack ermittelt, der Stackpointer entsprechend abgeändert und die Adresse auf dem Stack für den angeforderten Block übergeben.

    Exakt das gleiche passiert bei einem Array. Der einzige Vorteil bei einem Array ist, daß der Compiler weiß wie groß es ist. Das war's dann aber auch schon an Unterschieden.

    🙄
    Ich habe doch unten genau hingeschrieben, was ich daran nicht verstehe, und das ist auch schon beantwortet worden...


Anmelden zum Antworten