Adresse einer Funktion in einer Variable Speichern



  • audacia schrieb:

    Was die C++-Streams mit einem Funktionszeiger machen sollten, weiß ich nicht, aber wieso sollten Funktionszeiger nicht implizit nach void* konvertierbar sein?

    Erinnerst du dich an die Speichermodelle unter DOS? Tiny, Small, Medium, Compact, Large, Huge? Da gab es Fälle, in denen Daten mit near-Zeigern und Code mit far-Zeigern oder umgekehrt adressiert wurden. Der Standard ermöglicht sowas, indem er keine Umwandlung zwischen Daten- und Funktionszeigern vorsieht.



  • Zu dem Problem mit der Zeigergröße:

    #include <boost/integer.hpp>
    
    int main() {
        typedef boost::int_t<sizeof(void*)>::least address;
    }
    

  • Mod

    pyhax schrieb:

    Zu dem Problem mit der Zeigergröße:

    #include <boost/integer.hpp>
    
    int main() {
        typedef boost::int_t<sizeof(void*)>::least address;
    }
    

    Das kann ich (offiziell erst in C++11, aber das sollten auch sonst schon viele Compiler können, die eine C99-Standardbibliothek dabei haben) einfacher:

    #include <cinttypes>
    
    std::intptr_t address;
    


  • SeppJ schrieb:

    Das kann ich (offiziell erst in C++11, aber das sollten auch sonst schon viele Compiler können, die eine C99-Standardbibliothek dabei haben) einfacher:

    #include <cinttypes>
    
    std::intptr_t address;
    

    👍

    Das kannte ich noch nicht.



  • Bashar schrieb:

    audacia schrieb:

    Was die C++-Streams mit einem Funktionszeiger machen sollten, weiß ich nicht, aber wieso sollten Funktionszeiger nicht implizit nach void* konvertierbar sein?

    Erinnerst du dich an die Speichermodelle unter DOS? Tiny, Small, Medium, Compact, Large, Huge? Da gab es Fälle, in denen Daten mit near-Zeigern und Code mit far-Zeigern oder umgekehrt adressiert wurden.

    Ja, kenne ich gut.

    Bashar schrieb:

    Der Standard ermöglicht sowas, indem er keine Umwandlung zwischen Daten- und Funktionszeigern vorsieht.

    Verstehe ich nicht. Es ist grundsätzlich eine Umwandlung eines near-Zeigers in einen far-Zeiger möglich, andersherum aber nicht. Also wäre auch ein far-Funktionszeiger nicht in void*, sondern nur in void far* umwandelbar. Aber wo ist der Zusammenhang zwischen Speichermodellen, die verschiedene Zeigerbreiten unterstützen, und der Umwandlung von Funktions- nach Datenzeigern? Das sind doch völlig orthogonale Kriterien.

    *Edit:*Ich glaube, bei x86 werden near-Datenzeiger über DS adressiert, near-Funktionszeiger allerdings über CS, so daß sie nicht austauschbar sind. Vielleicht meinst du das?

    Edit 2: werden werden werden



  • Gibts near- und far Zeiger eigentlich noch unter x64 Systemen?



  • 314159265358979__ schrieb:

    Gibts near- und far Zeiger eigentlich noch unter x64 Systemen?

    Schon nicht mehr auf einigen (modernen) 32-Bit Systemen. Bei entsprechenden 32/64-Bit Systemen herrscht eine lineare Speicherverwaltung, wobei jeder Pointer auf jede x-beliebige Speicherzelle zeigen kann.



  • Jein. Die Segmentregister sind nach wie vor vorhanden, aber im Long-Mode werden sie nicht mehr zur Segmentierung verwendet (das war ja auch im 32-Bit-Protected-Mode schon unüblich, wäre aber noch gegangen). Einige werden komplett abgeschaltet, ein paar können aus Kompatibilitätsgründen noch benutzt werden (Zwischenzeitlich hat man einigenorts die Segmentregister, die man zur Segmentierung nicht mehr brauchte, für andere Zwecke missbraucht, unter Windows beispielsweise als Verweis auf threadlokale Daten).

    Near- und Far-Pointer a la 16-Bit-Real-Mode kann man im long mode nicht mehr betreiben, es hindert einen aber nichts daran, in andere Modi zu wechseln. Jedenfalls, wenn man ausreichend masochistisch veranlagt ist.



  • audacia schrieb:

    Bashar schrieb:

    Der Standard ermöglicht sowas, indem er keine Umwandlung zwischen Daten- und Funktionszeigern vorsieht.

    Verstehe ich nicht. Es ist grundsätzlich eine Umwandlung eines near-Zeigers in einen far-Zeiger möglich, andersherum aber nicht. Also wäre auch ein far-Funktionszeiger nicht in void*, sondern nur in void far* umwandelbar.

    Ja richtig, Funktionszeiger können dann nicht sinnvoll nach void* umgewandelt werden. void far* gibts im Standard nicht.

    Aber wo ist der Zusammenhang zwischen Speichermodellen, die verschiedene Zeigerbreiten unterstützen, und der Umwandlung von Funktions- nach Datenzeigern? Das sind doch völlig orthogonale Kriterien.

    Es geht ja auch nicht ums Unterstützen. Wenn deine Funktionszeiger grundsätzlich far sind und deine Datenzeiger grundsätzlich near (IIRC Speichermodell Medium), dann kannst du sie nicht sinnvoll ineinander umwandeln.

    *Edit:*Ich glaube, bei x86 werden near-Datenzeiger über DS adressiert, near-Funktionszeiger allerdings über CS, so daß sie nicht austauschbar sind. Vielleicht meinst du das?

    Das meinte ich eigentlich nicht, aber das ist ja ein ähnlich gelagertes Problem.



  • Bashar schrieb:

    Es geht ja auch nicht ums Unterstützen. Wenn deine Funktionszeiger grundsätzlich far sind und deine Datenzeiger grundsätzlich near (IIRC Speichermodell Medium), dann kannst du sie nicht sinnvoll ineinander umwandeln.

    Stimmt, das ist ein Argument.

    seldon schrieb:

    (Zwischenzeitlich hat man einigenorts die Segmentregister, die man zur Segmentierung nicht mehr brauchte, für andere Zwecke missbraucht, unter Windows beispielsweise als Verweis auf threadlokale Daten).

    Oder auch SEH unter 32-Bit-Windows. Dort ist FS:[0] stets der Verweis auf den Anfang der Liste der Exception-Handler.

    seldon schrieb:

    es hindert einen aber nichts daran, in andere Modi zu wechseln

    Das gilt natürlich nur, wenn du Betriebssystem bist. Ring 3 wird dich mit allen Kräften daran hindern, in den Real Mode zu wechseln.


Anmelden zum Antworten