struct initialisieren



  • Die meisten denken bei "struct" immer noch an C. Und da ging sowas nicht....



  • Jochen Kalmbach schrieb:

    Die meisten denken bei "struct" immer noch an C. Und da ging sowas nicht....

    Was geht bei C nicht? struct initialisieren?



  • Genau.... struct sind in C nun mal keine Klassen...



  • Wann hast du das letzte mal C programmiert?
    Ist wohl schon lange her.
    Selbstverständlich kann man in C structs initialisieren, sowohl implizit wie auch explizit über eine o.g. Initialisierungsliste.



  • Na dann sorry... hatte wohl einen alten Compiler... und noch älteren Source...



  • Bei POD-Strukturen gönne ich mir im Konstruktor des Structs gern mal ein memset, sofern eine initialisierung denn überhaupt sinn macht.



  • Es ist gerade mit WinAPI, dessen relevante Eigenheiten die MFC erben, auch empfehlenswert, eine Initialisierungsliste zu benutzen.

    Viele Structs im WinAPI (und den MFC) speichern ihre Länge, um Binärkompatibilität zwischen verschiedenen Versionen herzustellen. Die Idee ist, dass alte Binaries den Funktionen mitteilen, welche Version des Structs übergeben wurde und die Funktion das entsprechende Backend raussucht - auf die Art können die Structs später erweitert werden, ohne alte Programme zu beschädigen.

    Jetzt ist es in C so, dass Structs, wenn sie einfach nur erstellt werden, zunächst uninitialisiert sind. Das scheint kein Problem zu sein, wenn alle Member hinterher von Hand initialisiert werden, aber wenn eine spätere Windows-Version das Struct erweitert, hat man hinter dem vom alten Code initialisierten Teil neue, uninitialisierte Member und die Möglichkeit einer ganzen Reihe unangenehmer Effekte. Benutzt man dagegen eine Initialisierungsliste, wird alles, was man nicht explizit angibt, mit 0 beschrieben, und ich denke, man darf davon ausgehen, dass das in zukünftigen Revisionen das Verhalten nicht ändern wird.

    Man muss allerdings dazu sagen, dass man dem Compiler explizit mitgeben kann, für welche Windows-Version kompiliert werden soll (WINVER entsprechend setzen), und dass, wenn man das tut, einem nicht laufend neue Structs untergeschoben werden. Gleichwohl: Wenn man alten Code mit neuen Features aus neuen WinAPI-Versionen aufrüsten will, kann einen so etwas einholen.

    Ich bin vor einiger Zeit bei einer Migration nach 64-Bit-Windows (nicht in C, sondern in VBA-Code, aber die Wurzel des Problems war die selbe) darüber gestolpert, dass das OPENFILENAME-Makro in Windows 2000 drei neue Member bekommen hatte und die alte Version in Win64 nicht mehr unterstützt wird. Jetzt war das im VBA-Code einfach zu entdecken - das Struct musste in VBA von Hand nachgebaut werden, und die Funktion gab einen Fehlercode zurück, weil sie mit dem Struct nichts anfangen konnte - aber hätte ich in C etwa

    OPENFILENAME ofn;
    
    ofn.lStructSize = sizeof(OPENFILENAME);
    ofn.hwndOwner = NULL;
    // ...
    

    geschrieben und bei der Migration WINVER erhöht, um für Win64 kompilieren zu können, wären die neuen Member (von denen zwei bislang unbenutzt sind) voll mit Datenmüll gewesen und ich hätte einen Schrödinbug gehabt.



  • It0101 schrieb:

    Bei POD-Strukturen gönne ich mir im Konstruktor...

    Auf die Gefahr hin, daß ich mich bloßstelle:
    Was sind POD-Strukturen?
    (structs und unions kenne ich sehr wohl)

    Martin



  • "Plain Old Data" .. die Member der Strukturen liegen hintereinander im Speicher, daher kann man dort auch mit der groben Memset-Kelle drüber ziehen...

    also wenn das struct nur aus

    int, float, char, pointern,
    usw. besteht.
    Bei C müsste aber eigentlich alles POD sein oder täusch ich mich da?



  • memset für struct Variableninitialisierung zu verwenden ist zumindest für 0 overdesigned, simpler und weniger fehleranfällig ist das in jedem Fall funktionierende

    struct IrgendeineStruktur variable = {0};
    

    Funktioniert auch für Arrays.
    Globale und static Variablen sind bekanntlich immer 0 initialisiert, aus Gründen der Lesbarkeit ist aber hier ebenso eine entsprechende Initialisierung angebracht.


Anmelden zum Antworten