New-Operator, ist folgendes Definiert?



  • Naja, der Wert ist unbestimmt, aber das Verfahren, das auf ihn angewendet wird, definiert. Sofern nicht an anderer Stelle undefiniertes Verhalten erzeugt wird, jedenfalls. Ob und ggf. wann das nützlich ist, ist eine andere Frage - jedenfalls darf eine Implementation beispielsweise nicht, nur weil sie mit unbestimmten Werten arbeitet, SIGSEGV o.ä. schmeißen oder wild in der Gegend herumspringen oder die Festplatte formatieren.

    Zurück zum ursprünglichen Codestück: Meintest du eigentlich

    #include <vector>
    
    // ...
    
    std::vector<int> liste(1);
    
    liste[0] = 5;
    liste.resize(2);
    

    ?



  • Ändert man den Code wie folgt ab, dann werden alle Werte des Arrays mit dem Default-Konstruktor initialisiert. In dem Fall wären die Int-Werte 0;

    int *Liste = new int[1]();    //Gleichbedeutend mit int* Liste = new int();
    Liste[0] = 5;    //Oder: *Liste = 5 , da es nur ein Array-Element gibt
    Liste = new int[2](); 
    //Hier werden sowohl Liste[0], als auch Liste[1] den Wert 0 haben
    

    Nur, als kleine Info am Rande 😉



  • SeppJ schrieb:

    Was ist denn der Unterschied zwischen einem undefiniertem und einem unbestimmten Wert?

    Ein unbestimmter Wert heißt in dem Fall, dass es irgendein Wert im erlaubten Wertebereich ist. Undefiniert hieße hier entweder, dass durch den Standard garnichts definiert wird (was nicht der Fall ist, wie man auch dem ersten Teil deines Satzes entnehmen kann), oder dass der Standard von undefiniert spricht, was im Sprachgebrauch des Standards normalerweise sowas wie "katastrophal" bedeutet. Ein "undefinierter Wert" im Sprachgebrauch des Standards würde bedeuten, dass der Zugriff darauf, bzw. das Benutzen des Wertes undefiniertes Verhalten zur Folge hätte.



  • pumuckl schrieb:

    Ein unbestimmter Wert heißt in dem Fall, dass es irgendein Wert im erlaubten Wertebereich ist. Undefiniert hieße hier entweder, dass durch den Standard garnichts definiert wird (was nicht der Fall ist, wie man auch dem ersten Teil deines Satzes entnehmen kann), oder dass der Standard von undefiniert spricht, was im Sprachgebrauch des Standards normalerweise sowas wie "katastrophal" bedeutet. Ein "undefinierter Wert" im Sprachgebrauch des Standards würde bedeuten, dass der Zugriff darauf, bzw. das Benutzen des Wertes undefiniertes Verhalten zur Folge hätte.

    Ich glaube mit der Interpretation von "indeterminate value" als ein Wert, der garantiert im gültigen Wertebereich liegt, lehnst du dich ziemlich weit aus dem Fenster. Dann müsste der Compiler ja im Allgemeinen doch Initialisierungscode erzeugen, wo doch die Intention an der Stelle gerade ist, dass das Objekt uninitialisiert bleibt.
    Undefiniert kann nur Verhalten sein. Ein Wert kann ungültig sein, was für sich genommen noch nicht tragisch ist, man darf ihn halt einfach nicht benutzen.



  • Bashar schrieb:

    Ich glaube mit der Interpretation von "indeterminate value" als ein Wert, der garantiert im gültigen Wertebereich liegt, lehnst du dich ziemlich weit aus dem Fenster.

    IIRC haben PODs (um die es ja hier geht) einen Wertebereich, der alle möglichen Speicherbelegungen umfasst und müssen daher nicht speziell initialisiert werden. Anders ausgedrückt, haben PODs auch ohne Initialisierung immer einen gültigen Wert. Das geht auch aus den Abschnitten zur "Object lifetime" im Standard implizit hervor.

    Bashar schrieb:

    Undefiniert kann nur Verhalten sein.

    Stimmt allerdings, ich habe nochmal nachgeschaut und nirgends was zu undefinierten Werten gelesen. Unter dem Aspekt ist allerdings das Zitat von SeppJ auch nicht richtig im Sinne des Standards.

    Bashar schrieb:

    Ein Wert kann ungültig sein, was für sich genommen noch nicht tragisch ist, man darf ihn halt einfach nicht benutzen.

    Kann er das? Nach allem was ich beim Überfliegen des Standards gelesen habe haben Objekte immer einen Wert, der entweder durch den Standard klar definiert, implementation defined oder eben indetermined ist. (Indetermined ist übrigens nicht implementation defined, letzteres bedeutet, dass Compiler den Wert definieren.)
    Ein "ungültiger Wert" wäre vielleicht der Wert eines non-POD Objektes nach Allokation, aber vor Initialisierung bzw. nach Zerstörung, aber vor Deallokation - was im Sinne des Standards aber außerhalb der Lebenszeit des Objektes ist, so dass es da strenggenommen keinen Wert haben kann, auch keinen ungültigen. Der Zugriff auf ein solches nichtexistentes Objekt ohne gültigen Wert führt natürlich auch wieder zu undefiniertem Verhalten.



  • pumuckl schrieb:

    Bashar schrieb:

    Ich glaube mit der Interpretation von "indeterminate value" als ein Wert, der garantiert im gültigen Wertebereich liegt, lehnst du dich ziemlich weit aus dem Fenster.

    IIRC haben PODs (um die es ja hier geht) einen Wertebereich, der alle möglichen Speicherbelegungen umfasst und müssen daher nicht speziell initialisiert werden. Anders ausgedrückt, haben PODs auch ohne Initialisierung immer einen gültigen Wert. Das geht auch aus den Abschnitten zur "Object lifetime" im Standard implizit hervor.

    Klassisches Beispiel: bool. Alles außer 0 und 1 sind keine gültigen Werte. Unter "Object lifetime" steht übrigens gar nichts über Werte. Dafür aber in 3.9§2: "For any complete POD object type T, whether or not the object holds a valid value of type T, ...", wodurch die Möglichkeit ungültiger Werte definitiv eingeräumt wird.
    Ansonsten muss man in den C-Standard gucken, der in der Beziehung weit ausführlicher ist, z.B. steht unter 6.2.6.1§5 (draft c99):
    "Certain object representations need not represent a value of the object type. If the stored value of an object has such a representation and is accessed by an lvalue expression that does not have character type, the behavior is undefined. If such a representation is produced by a side effect that modifies all or any part of the object by an lvalue expression that does not have character type, the behavior is undefined.37) Such a representation is called atrap representation. "
    Der C++-Standard sagt das nicht ausführlich, aber er sagt auch nur für char-Typen explizit, dass jedes Bit eines Objektes zum Wert beiträgt, bei den anderen Typen fehlt das.

    Bashar schrieb:

    Undefiniert kann nur Verhalten sein.

    Stimmt allerdings, ich habe nochmal nachgeschaut und nirgends was zu undefinierten Werten gelesen. Unter dem Aspekt ist allerdings das Zitat von SeppJ auch nicht richtig im Sinne des Standards.

    SeppJ hatte "nicht definiert" gesagt, nicht "undefiniert", und schon gar nicht hat er sich auf Verhalten bezogen. Was der Wert ist, ist in der Tat "nicht definiert".

    Ein "ungültiger Wert" wäre vielleicht der Wert eines non-POD Objektes nach Allokation, aber vor Initialisierung bzw. nach Zerstörung, aber vor Deallokation

    Über non-POD reden wir ja gar nicht.



  • Ich seh schon, ich muss mich da nochmal genauer einlesen.

    Allerdings:

    Bashar schrieb:

    Klassisches Beispiel: bool. Alles außer 0 und 1 sind keine gültigen Werte. [...]
    Der C++-Standard sagt das nicht ausführlich, aber er sagt auch nur für char-Typen explizit, dass jedes Bit eines Objektes zum Wert beiträgt, bei den anderen Typen fehlt das.

    Es ist zwar klar, dass sizeof(bool) >= 1 und damit ein bool aus mehr als einem bit bestehen muss. Wenn der Standard aber nur für chars explizit sagt, dass jedes Bit zählt, heißt das im Umkehrschluss, dass für bool durchaus nur ein Bit zählen kann. Dann ist die Belegung der restlichen Bits irrelevant für den Wert und es gibt nur die Werte true und false.

    Allerdings schweift die Diskussion damit wohl arg ab 😉
    Ich nehme meine Aussage also zurück:

    SeppJ schrieb:

    Wenn ja, was ist in Liste[0]?

    Es ist definiert, dass das nicht definiert ist 😃

    [/quote]
    Ist nicht falsch - nur in meinen Augen ungenau ausgedrückt.


  • Mod

    Wow, das so eine scherzhaft rhetorisch aufgemotzte Nebenbemerkung doch auslösen kann. 🕶



  • pumuckl schrieb:

    Es ist zwar klar, dass sizeof(bool) >= 1 und damit ein bool aus mehr als einem bit bestehen muss. Wenn der Standard aber nur für chars explizit sagt, dass jedes Bit zählt, heißt das im Umkehrschluss, dass für bool durchaus nur ein Bit zählen kann. Dann ist die Belegung der restlichen Bits irrelevant für den Wert und es gibt nur die Werte true und false.

    Dann müssten die restlichen Bits ja immer ausmaskiert werden. Das will der Standard natürlich nicht von den Compilerbauern fordern. Siehe Fußnote 42 zu 3.9.1§6: "Using a bool value destribed in this internation standard as «undefined», such as by examining the value of an uninitialized automatic variabe, might cause it to behave as if it is neither true nor false."

    Allerdings schweift die Diskussion damit wohl arg ab 😉

    Ja, ich würde auch vorschlagen, das wir das beenden. Dieses elende Blättern im Standard ist ein extremer Zeitfresser.



  • SeppJs Aussage war doch, dass der Wert undefinert ist, und nicht das Verhalten. Und die Aussage ist so korrekt.

    Edit: Ups, ich habe übersehen, dass es inzwischen eine zweite Seite im Thread gibt


Anmelden zum Antworten