Zeiger auf irgendwas immer 4 Byte gross ?



  • hustbaer schrieb:

    Ein normaler Zeiger auf DATEN ist im Normalfall immer gleich gross.

    ...und was ist für dich der normalfall?


  • Mod

    Grundsätzlich können verschiedene Pointertypen verschiedene Größen haben. Das wird nur dadurch eingeschränkt, dass Pointer, deren Pointee sich nur durch cv-Qualifikation (evtl. auch nur in höheren Indirektionsebenen) unterscheiden dieselbe Representation haben. Gleichermaßen sind char* und void* identisch hinsichtlich der Representation. Mir ist allerdings kein Compiler bekannt, der das tut (mein Erfahrungshorizont ist aber auch sehr beschränkt). Ein Hinweis im Standard ist der, dass die Umwandlung eines Pointers in einen anderen dann undefiniertes Verhalten ist, wenn die Alignmentvoraussetzungen des Zielpointers größer sind und das Argument nicht gerade durch vorherige Umwandlung des Zielpointers in das Argument entstanden ist. Beispiel: Unsere Maschine möge eine Wortbreite von 32bit haben, d.h. hardwareseitig sind nur 32bit Wörter direkt adressierbar. Unser Compiler soll allerdings für char trotzdem nur 8bit benötigen. Ein char pointer würde dann intern etwa so aufgebaut sein:

    struct char_pointer
    {
        native_pointer p;
        unspecified select : 2;
    }
    

    wir benötigen also noch zwei zusätzliche bit, um das jeweilige char zu ermitteln. Für Datentypen mit einem Alignment von 4 (also z.b. ein 32bit int auf dieser Plattform) sind diese zusätzlichen Bit allerdings unnötig, Der Compiler könnte einen int-Zeiger unmittelbar auf den hardwareseitig unterstützten Pointer abbilden. Nun ist aber klar, dass bei der Umwandlung eines char* in ein int* auf dieser Plattform Information verlorengeht.
    Aus Sicht der Implementation wird das Ganze aber extrem problematisch, wenn unvollständige Datentypen (abgesehen von void) ins Spiel kommen. Beispiel:
    ÜE1:

    struct T { char x; };
    struct U { int y; };
    
    U* cast(T* p);
    
    void foo()
    {
        T* p = ...
        U* q = cast( p );
        // ...
    }
    

    ÜE2:

    struct T;
    struct U;
    
    U* cast(T* p) { return reinterpret_cast< U* >( p ); }
    

    Der Compiler wird in der Funktion cast die genaue Representation von T* und U* kennen müssen, um Code zu erzeugen. T und U sind aber dort unvollständig. Das ist ein Problem wenn getrennt übersetzt wird und die Pointerrepräsentation vom Typ des Pointees abhängt.



  • @lolz

    dein code gibt bestimmt nicht die größe eines Zeigers aus mit & werden referenzen angegeben oder addresse eines objekts zurückgegeben.Zeiger werden mit * gekennzeichnet.



  • walljumper schrieb:

    @lolz

    dein code gibt bestimmt nicht die größe eines Zeigers aus mit & werden referenzen angegeben oder addresse eines objekts zurückgegeben.Zeiger werden mit * gekennzeichnet.

    Wenn man keine Ahnung hat...



  • dann erklärs mir



  • &foo ist ein Zeiger auf foo.



  • sorry aber bei mir ist foo* ein Zeiger &foo gibt bei mir die addresse von foo zurück.



  • walljumper schrieb:

    sorry aber bei mir ist foo* ein Zeiger

    Nein, das ist ein Syntaxfehler (foo ist eine Variable, eine Funktion, etc. - kein Typ!)

    &foo gibt bei mir die addresse von foo zurück.

    Und das ist was anderes als ein Zeiger???



  • Nein, das ist ein Syntaxfehler (foo ist eine Variable, eine Funktion, etc. - kein Typ!)

    du hast nicht geschrieben was foo ist ^^

    naja ne addresse ist für mich schon was anderes als ein Zeiger ne addresse ist ein Wert. Ein Zeiger eine Variable die einen Wert enthält.



  • SG1 schrieb:

    &foo gibt bei mir die addresse von foo zurück.

    Und das ist was anderes als ein Zeiger???

    ist es:

    int *p = &intvariable; // links ist ein zeiger, rechts ist eine adresse
    

    :xmas2:



  • walljumper schrieb:

    Nein, das ist ein Syntaxfehler (foo ist eine Variable, eine Funktion, etc. - kein Typ!)

    du hast nicht geschrieben was foo ist ^^

    Hallo? Kontext? Versteht sich ja wohl von selbst, dass ich mich auf den Beitrag von lolz bezogen hab.



  • also erstmal:

    ein Zeiger ist eine Variable und speichert NICHT irgendeinen Wert, sondern IMMER eine Adresse.
    Dabei ist der Typ völlig unbedeutend, ein Zeiger ist immer gleich groß, zumindest auf der gleichen Plattform.
    So ist zum Beispiel ein Zeiger im Real-Mode des Prozessors IMMER 16 Bit
    (2 Byte) groß.
    Im Protected-Mode, wo auch Win32 arbeitet, ist jeder Zeiger 32 Bit (4 Byte) groß.
    Und bei 64 Bit-Windows, was logischer Weise nur auf einem Prozessor mit 64 Bit laufen kann, wird ein Zeiger IMMER 64 Bit oder 8 Byte groß sein.

    Wer mehr dazu wissen möchte, sollte sich mit Assembler befassen, da wird einem das ganze erklärt.

    MfG DrakoXP



  • DrakoXP schrieb:

    ein Zeiger ist immer gleich groß, zumindest auf der gleichen Plattform.

    falsch.


  • Mod

    DrakoXP schrieb:

    also erstmal:

    ein Zeiger ist eine Variable und speichert NICHT irgendeinen Wert, sondern IMMER eine Adresse.
    Dabei ist der Typ völlig unbedeutend, ein Zeiger ist immer gleich groß, zumindest auf der gleichen Plattform.
    So ist zum Beispiel ein Zeiger im Real-Mode des Prozessors IMMER 16 Bit
    (2 Byte) groß.
    Im Protected-Mode, wo auch Win32 arbeitet, ist jeder Zeiger 32 Bit (4 Byte) groß.
    Und bei 64 Bit-Windows, was logischer Weise nur auf einem Prozessor mit 64 Bit laufen kann, wird ein Zeiger IMMER 64 Bit oder 8 Byte groß sein.

    Wer mehr dazu wissen möchte, sollte sich mit Assembler befassen, da wird einem das ganze erklärt.

    MfG DrakoXP

    Was ist ein Fensters?
    Komisch, dass mir unter DOS ständig 4Byte-Far-Pointer über den Weg gelaufen sind...

    Was irgendein assembler zum Thema Pointer zu sagen hat, ist in C++ (zunächst) völlig irrelevant. Und wie bereits erwähnt, es gibt nur beschränkte Garantien. Im Übrigen sollten solche Unterschiede bei sauberer Programmierung keinen Unterschied machen. Funktioniert etwas bei veränderter Größe plötzlich nicht mehr, dürfte dem in 99% aller Fälle von vornherein ein Logikfehler zugrunde liegen.



  • Hallo? Kontext? Versteht sich ja wohl von selbst, dass ich mich auf den Beitrag von lolz bezogen hab.

    da kommt aber auch kein foo vor.

    &foo ist ein Zeiger auf foo.

    versteh ich so:
    &int ist ein Zeiger auf int.

    und das ist falsch.
    btw: wenn foo eine int Variable ist stimmt der satz auch nicht dann gibt &foo die adresse von foo zurück.

    ein Zeiger ist immer gleich groß, zumindest auf der gleichen Plattform.

    falsch.

    dann erklärs uns doch. Anstatt nur "falsch" zu schreiben das hilf niemandem weiter.



  • walljumper schrieb:

    btw: wenn foo eine int Variable ist stimmt der satz auch nicht dann gibt &foo die adresse von foo zurück.

    Ein Zeiger ist ein Typ. Eine Adresse ein Wert. Soweit richtig. Aber in C++ haben alle Werte in ihrem Kontext einen Typ, und sizeof gibt eben die Größe eines Typs in Byte zurück. Und was glaubst Du was eine Adresse (&foo) im Kontext sizeof dann für einen Typ hat? double?



  • walljumper schrieb:

    ein Zeiger ist immer gleich groß, zumindest auf der gleichen Plattform.

    falsch.

    dann erklärs uns doch. Anstatt nur "falsch" zu schreiben das hilf niemandem weiter.

    camper hat auf Seite 1 eine wunderbare Erklaerung geschrieben.



  • walljumper schrieb:

    &foo ist ein Zeiger auf foo.

    versteh ich so:
    &int ist ein Zeiger auf int.

    und das ist falsch.
    btw: wenn foo eine int Variable ist stimmt der satz auch nicht dann gibt &foo die adresse von foo zurück.

    Ne du, deine Einwände stimmen imho nicht. Ist foo vom Typ int, dann ist &foo vom Typ int*, also ein Zeiger. Dass da ne Adresse drin stehen kann ist ne andere Sache.
    Auch dein Verständnis ist nicht ganz richtig. Man sagt nicht, foo* ist Zeiger auf foo, sondern foo* ist der Typ eines Zeigers auf foo. Das sind elementar verschiedene Sachen.



  • LordJaxom schrieb:

    Und was glaubst Du was eine Adresse (&foo) im Kontext sizeof dann für einen Typ hat? double?

    size_t ?



  • Ne du, deine Einwände stimmen imho nicht. Ist foo vom Typ int, dann ist &foo vom Typ int*, also ein Zeiger. Dass da ne Adresse drin stehen kann ist ne andere Sache.

    hmm klingt einleuchtend obwohl mein It Lehrer das anders gesagt naja vieleicht auch nur damit es auch die anderen Verstehen.

    Auch dein Verständnis ist nicht ganz richtig. Man sagt nicht, foo* ist Zeiger auf foo, sondern foo* ist der Typ eines Zeigers auf foo. Das sind elementar verschiedene Sachen.

    siehe oben

    Und was glaubst Du was eine Adresse (&foo) im Kontext sizeof dann für einen Typ hat? double?

    size_t ?

    Ich glaub er meinte den Wert.

    Naja und das wird 4 sein.

    camper hat auf Seite 1 eine wunderbare Erklaerung geschrieben.

    Das erklärt aber nicht das Verhalten von lolzs code. Es erklärt nur das ein Zeiger auf ein Datum das kleiner ist als die Wortbreite einen größeren Zeiger benötigt. Selbst wenn man ein einzelnes Bit adressieren wollte bräuchte man auf einer x86 maschine höchstens 4byte und 3 Bit der code von lolz gibt aber 12 aus es kann also kein zeiger sein.

    Da es in C++ keinen Datentyp gibt der kleiner als 1Byte ist und die normale Wortbreite 1Byte ist sind alle Zeiger gleich groß.


Anmelden zum Antworten