C/C++ Initialisierungslisten



  • Währe echt super wenn jemand aufklären könnte ob hier eine value-Initialisierung stattfindet oder nicht.



  • sqrt(-1) schrieb:

    Währe echt super wenn jemand aufklären könnte ob hier eine value-Initialisierung stattfindet oder nicht.

    Meinst du den folgenden Code?

    #include "Deklaration.h"
    
    class Klasse
    {
       private:
         Daten daten;
       public:
         Klasse() {}
    };
    

    Wenn der Typ Daten hier ein POD ist, wird die Variable daten nicht initialisiert. Ist Daten eine Klasse mit Standardkonstruktor, so wird dieser im Klasse -Konstruktor implizit aufgerufen. Um eine Initialisierung (bei PODs durchgehend mit 0) zu garantieren, nimm LordJaxoms Variante.



  • OK, und was passiert bei verschachtelten POD Typen? Wird die value-Initialisierung durchgereicht?



  • sqrt(-1) schrieb:

    OK, und was passiert bei verschachtelten POD Typen? Wird die value-Initialisierung durchgereicht?

    Was meinst du mit "verschachtelten POD Typen"? Entweder man hat einen Build-In Typen, dann ists klar(wurde ja auch schon genug erklärt) oder ne Klasse und da hat man nen (wenn nicht selbst geschrieben, dann compiler generierten) Standard-Konstruktor
    Wenn dus nicht beschreiben kannst, versuchs halt mit Code zu skizzieren^^

    bb



  • unskilled schrieb:

    Was meinst du mit "verschachtelten POD Typen"?

    Er meint sicher sowas in der Art:

    struct Daten
    {
        int a;
        double b;
    };
    
    class Klasse
    {
       private:
         Daten daten;
       public:
         Klasse() : daten() {}
    };
    

    Werden hier daten.a und daten.b korrekt initialisiert? Ich bild mir ein, dafür müsste man in Daten den Standard-Ctor überschreiben, aber genau weiß ich das nicht.



  • XMaster, für dein Beispiel wurde bereits beschrieben dass eine value-Initialisierung vorgenommen wird.

    Ich meine:

    struct Daten
    {
        struct
        {
           int y;
           char text[8];
        }textDaten;
    
        int a;
        double b;
    };
    
    class Klasse
    {
       private:
         Daten daten;
       public:
         Klasse() : daten() {}
    };
    

    Wie sieht es denn eigentlich damit aus:

    class Klasse
    {
       private:
         int a;
         int b[20];
         int c;
       public:
         Klasse() : a() {}
    };
    

    Soweit ich das bisher angenommen habe müsste b und c eigentlich nicht initialisiert sein. Jedoch ergeben meine Tests das Gegenteil.



  • unskilled schrieb:

    Entweder man hat einen Build-In Typen, dann ists klar [...] oder ne Klasse

    Es gibt nicht nur BuiltIns und Klassentypen in C++. Und selbst bei Klassen kann das Initialisierungsverhalten so unterschiedlich sein, dass es sich nicht auf den ersten Blick ergibt.

    XMaster schrieb:

    Werden hier daten.a und daten.b korrekt initialisiert?

    Wenn du mit korrekt null-initialisiert meinst, dann ja.

    Sofern ein POD initialisiert wird (über Aggregats-Initialisierungsliste oder Klammersyntax), haben alle Werte einen definierten Wert, welcher der Repräsentation von Null im jeweiligen Bitmuster entspricht, wenn nichts weiter angegeben wird.

    // Sei Daten ein POD-Typ.
    Daten a;           // KEINE Initialisierung
    Daten b = Daten(); // initialisiert b vollständig mit Nullen.
    Daten c = {};      // ebenfalls
    

    sqrt(-1) schrieb:

    Soweit ich das bisher angenommen habe müsste b und c eigentlich nicht initialisiert sein. Jedoch ergeben meine Tests das Gegenteil.

    Du hast Recht, b und c müssen nicht initialisiert werden. Dass sie es trotzdem zu sein scheinen, ist entweder ein Zusatzfeature des Compilers, oder Zufall. Solche Dinge lassen sich durch Tests nicht wirklich beweisen.

    In diesem Zusammenhang sei zudem auf folgenden Thread verwiesen:
    http://www.c-plusplus.net/forum/viewtopic-var-t-is-249075.html



  • Sie enthalten zufällige (undefinierte Daten). Es kann aber sein, dass dein Compiler dir da eine gewisse Initialisierung macht (im Debug Mode von VS z.B)



  • {edit: oh - wieder was dazu gelernt ;D}

    sqrt(-1) schrieb:

    class Klasse
    {
       private:
         int a;
         int b[20];
         int c;
       public:
         Klasse() : a() {} //a wird mit int() initialisiert
    };
    

    also:
    a = 0
    b[0 ... 20] = {random}
    c = {random}

    sqrt(-1) schrieb:

    Soweit ich das bisher angenommen habe müsste b und c eigentlich nicht initialisiert sein. Jedoch ergeben meine Tests das Gegenteil

    Viele Compiler initialisieren im Debug-Mode die Variablen trotzdem (MSVC macht das glaube ich z.bsp. auf 0xc{...}c

    bb



  • "Zufällig" ist in in diesem Kontext eigentlich nicht ganz korrekt, "undefiniert" trifft es besser. Der Begriff der Zufälligkeit legt nahe, dass es sich um ein ähnliches Vorgehen wie beim Würfeln oder bei Pseudozufallsgeneratoren handelt, das stimmt aber nicht. Uninitialisierten Speicher als Quelle von Zufallszahlen zu nehmen ist aus diesem Grund auch sinnfrei (es gibt ab und zu wieder solche Ideen).

    Ausserdem denkt man bei "Zufall" an gewisse Eigenschaften wie Gleichverteilung der Werte, wodurch einem eine ständige Null sehr unwahrscheinlich vorkommt. Eine Null kann aber sehr wohl auftreten, obwohl keine Initialisierung stattgefunden hat. Und zwar, wenn an dieser Speicherstelle noch Nullen stehen (die zum Beispiel aus der Initialisierung eines früheren Objekts resultieren).



  • Ist nun die beschriebene verschachtelte Struktur ein POD Typ und wird im Beipiel komplett mit Null initialisiert?



  • Ich finde "Zufällig" durchaus passend. Man sollte dann aber mal ein wenig über den philosophischen Aspekt von Zufall Gedanken machen. Zufall erlaubt jegliche Kombination in jeglicher Reihenfolge. Wenn ich z.B 1000 mal mit einem Würfel die Zahl 6 würfle, dann ist (besser: kann) das VOLKOMMEN Zufällig sein (sofern er nicht getürkt ist). Durchaus unwahrscheinlich aber möglich. Wenn ich z.B unendlich mal würfle, dann kommt diese Kombination garantiert zu stande.



  • sqrt(-1) schrieb:

    Ist nun die beschriebene verschachtelte Struktur ein POD Typ und wird im Beipiel komplett mit Null initialisiert?

    Wurden dazu nicht bereits genügend Aussagen gemacht? Ausserdem wäre es gut, wenn du sagst, auf welches Beispiel mit welchem verschachtelter Struktur du dich beziehst (schreib nochmals den Code hin).

    drakon schrieb:

    Ich finde "Zufällig" durchaus passend. Man sollte dann aber mal ein wenig über den philosophischen Aspekt von Zufall Gedanken machen. Zufall erlaubt jegliche Kombination in jeglicher Reihenfolge. Wenn ich z.B 1000 mal mit einem Würfel die Zahl 6 würfle, dann ist (besser: kann) das VOLKOMMEN Zufällig sein (sofern er nicht getürkt ist). Durchaus unwahrscheinlich aber möglich. Wenn ich z.B unendlich mal würfle, dann kommt diese Kombination garantiert zu stande.

    Ja, aber mit dieser Interpretation wird der Begriff des Zufalls völlig verwaschen, weil dann plötzlich alles zufällig ist, schliesslich kann es ja bei unendlich häufigem Würfeln vorkommen.

    Ich finde es wichtig, eine zumindest einigermassen übliche Grenze zu ziehen (d.h. den Unterschied von PRNGs und Würfeln mal beiseite zu lassen, und Quanteneffekte erst recht). Meiner Meinung nach versteht man Zufall umgangssprachlich so, dass jeder Wert eine gleich grosse Chance hat, aufzutreten. Das ist im Beispiel hier eindeutig nicht so und wird auch bei noch so vielen Versuchen nicht so sein (einfach aufgrund der Tatsache, dass der Wert Null eine spezielle Behandlung hat und für viele Dinge als Initial- oder Defaultwert verwendet wird).

    Ich habe hier auf die Terminologie hingewiesen, weil im von mir verlinkten Thread eben genau dieser Fehlschluss gemacht wurde.



  • Nexus schrieb:

    Wurden dazu nicht bereits genügend Aussagen gemacht? Ausserdem wäre es gut, wenn du sagst, auf welches Beispiel mit welchem verschachtelter Struktur du dich beziehst (schreib nochmals den Code hin).

    Ich konnte aus den Antworten nicht herauslesen ob die Struktur "Daten" als POD Typ gilt und hier im Beispiel komplett mit Null initialisiert wird.

    sqrt(-1) schrieb:

    Ich meine:

    struct Daten
    {
        struct
        {
           int y;
           char text[8];
        }textDaten;
    
        int a;
        double b;
    };
    
    class Klasse
    {
       private:
         Daten daten;
       public:
         Klasse() : daten() {}
    };
    


  • Ich habe eben nochmal ohne Erfolg versucht das aus dem Standard rauszulesen.
    Währe wirklich toll wenn jemand darauf eine Antwort hätte.



  • Ja, deine Struktur ist ein POD und wird demnach 'value-initialized' (also mit 0 initialisiert).
    Dies gilt rekursiv auch für alle darin enthaltenen Strukturen, d.h. auch y und das char-Array text werden 'genullt'.

    Sobald du jedoch innerhalb deiner Struktur einen Nicht-POD-Typ hast, kannst du dich darauf nicht mehr verlassen.
    Üblicherweise wird dabai von den Compilern intern 'memset(daten, sizeof(daten), 0)' erzeugt (oder eine ähnliche Funktion) und nicht die einzelnen Strukturmember separat initialisiert.
    Stell es dir daher so etwa vor:

    if(Daten is POD type)
      WriteAsm("memset(daten, sizeof(daten), 0);")
    

    Wenn du Assemblerkenntnisse hast, dann kannst du ja mal den ASM-Output deiner Klasse anschauen.


Anmelden zum Antworten