structs und "gemeinsamer Speicherbereich"



  • Hallo,
    ich habe eine prinzipielle Frage bezüglich der Funktionalität und ob dieser eigentlich generell funktionieren sollte:

    struct FlagData
    {
        unsigned int flags;
    };
    
    typedef struct FlagData *Flags;
    
    struct SomeOtherStructWithFlags
    {
        unsigned int flags;
        char  content[20];
        /** some other things here */
    }
    
    typedef struct SomeOtherStructWithFlags *SoWFlags;
    
    int main (int argc, char ** argv)
    {
        // allokation etc
        SoWFlags bla = malloc(sizeof(struct SomOtherStructWithFlags));
        Flags f;
        bla->flags = UINT_MAX;
        f = (Flags) bla;
        f->flags = 42;    
    
        return 0;
    }
    

    Soweit so gut. Das funktioniert so. Aber funktioniert dieser Code, wenn ich verschiedene Structs habe, die alle dieses unsigned int flag besitzen an erster Stelle im Struct?
    Das konkrete Problem ist, dass ich verschiedene structs habe, die allerdings alle Flags besitzen (sollen). Einen Teil des Codes kann ich eher schlecht verändern(ich möchte ihn eigentlich nicht verändern), der bereits diese Flags benutzt. Allerdings möchte ich verschiedene structs, deren Typen ich nicht im Detail kenne innerhalb einer Funktion, auf die beinhalteten flags prüfen.
    Jetzt ist meine prinzipielle Frage:
    Funktioniert die Zuweisung und der Zugriff auf die flags in diesem Fall immer (müsste eigentlich schon, wenn ich richtig denke aufgrund dessen, dass ja zumindest der erste Teil des Speicherbereichs identisch ist)?

    Danke im Voraus

    Viele Grüße
    vorden



  • Ist nicht portabel, also solltest du von solchen Hacks die Finger lassen.



  • Hi,
    inwiefern ist das nicht portabel? Bräuchte ein wenig mehr Input.



  • Um den Code zu optimieren ist es dem Compiler freigestellt Elemente in der Struktur neu zu ordnen und Paddings einzufügen.



  • Kann man das über bestimmte Optionen vielleicht (jetzt mal in Bezug auf gcc 4.2.1) deaktivieren?



  • Janjan schrieb:

    Um den Code zu optimieren ist es dem Compiler freigestellt Elemente in der Struktur neu zu ordnen und Paddings einzufügen.

    Paddings einfügen ja, aber dass der Compiler einfach so die Elemente umordnet, wäre mir neu. Bitte Quelle angeben.



  • Also prinzipiell muss ich mir keine Gedanken machen, solange ich lediglich auf das erste Element zugreife, da normalerweise ja dann hinterher gepadded würde, soweit ich jetzt mal supertux komplett uneingeschränkt Glauben schenke, oder? Allerdings wäre ja dann wahrscheinlich das Padding bei mehreren, zumindest im Beginn gleichen Structs ja auch gleich, oder?



  • Ich kann mich auch irren, aber irgendwie habe ich noch im Hinterkopf, dass der Compiler die Ordnung der Elemente nicht verändern darf.

    Viele Frameworks (wie GTK+) leben eben davon, dass das erste Element eines Strukts stets am Anfang positioniert ist, deshalb kann ich mir das kaum vortsellen.



  • Elemente dürfen nicht umgeordnet werden und padding vor dem ersten Element darf es nicht geben.



  • supertux schrieb:

    Ich kann mich auch irren, aber irgendwie habe ich noch im Hinterkopf, dass der Compiler die Ordnung der Elemente nicht verändern darf.

    Ja, das ist richtig.
    Die Reihenfolge ist fest und das erste Byte der ganzen Struct im Speicher muß das erste Byte des ersten Elements sein.



  • Ich habe mal nachgelesen, dass Padding dann eingefügt würd, wenn ein Typ, der mehr als 2 Byte belegt, auf ungeraden Speicheradressen liegt (jedenfalls häufig). Somit wäre es ja kein Problem, beispielsweise anstatt ein unsigned int ein char [4] beispielsweise zu verwenden, oder gibts bei Arrays dasselbe mit Padding?
    Wenn ich quasi nur auf char[] zugreifen würde und beispielsweise dann einen Cast durchführen würde (oder memcpy, ...) dann müsste das Ganze doch prinzipiell überhaupt kein Problem darstellen und ich hätte auch Padding umgangen.
    EDIT:
    bzw wenn ich zwei Strukturen habe, die in den ersten Membern absolut identisch sind, müsste ich doch beide casten können ohne Probleme zu erzeugen.


Anmelden zum Antworten