dereferenziert &array[X]?



  • Also [4] ist natürlich außerhalb des gültigen Bereichs. Damit ist es wohl undefiniertes Verhalten. Dennoch würde ich sagen, dass array[size] doch einfach *(array + size) entspricht. Und damit entspricht &array[size] eben auch array + size, oder nicht?

    Wahrscheinlich wieder so ein Standarddetail, ob irgendwo vorher undefiniertes Verhalten auftritt. Wäre der Index gültig, wären die Ausdrücke jedenfalls äquivalent, wenn ich mich nicht erheblich täusche.



  • Eisflamme schrieb:

    Also [4] ist natürlich außerhalb des gültigen Bereichs. Damit ist es wohl undefiniertes Verhalten. Dennoch würde ich sagen, dass array[size] doch einfach *(array + size) entspricht. Und damit entspricht &array[size] eben auch array + size, oder nicht?

    Wenn der Compiler ordentlich optimiert, ja. (In diesem Fall dürfte wohl sowieso das ganze Statement ignoriert werden)



  • Sorry für oben, nicht genau genug geschaut.
    Ja, beides dasselbe. Solange du nicht versuchst die sich daraus ergebende Adresse zu dereferenzieren auch nicht UB.



  • Swordfish schrieb:

    Solange du nicht versuchst die sich daraus ergebende Adresse zu dereferenzieren auch nicht UB.

    Also ist auch array[size] kein UB? Oder ist es nur dank dem Adressoperator irrelevant?

    Ich bin mir verdammt sicher, dass das Dereferenzieren eines wilden Pointers UB ist...



  • Sone schrieb:

    Also ist auch array[size] kein UB?

    Ich weiß nicht, wie's der Standard damit hält, aber kein Compiler wird bei

    array[ sonstwas ];
    

    dereferenzieren. Wofür denn auch?

    Sone schrieb:

    Oder ist es nur dank dem Adressoperator irrelevant?

    Damit sollte es totsicher sein.

    Sone schrieb:

    Ich bin mir verdammt sicher, dass das Dereferenzieren eines wilden Pointers UB ist...

    Wenn du damit etwas wie

    char *ptr = 123;
    *ptr = 42;
    // oder:
    printf( "%d", *ptr );
    

    meinst, ja.



  • Nein, ich meine gerade generell, sowas wie

    int arr[] = {1,2};
    std::cout << arr[2];//Dereferenzierung eines wilden Zeigers
    

    Und nicht das Beispiel von vorhin, klar dass das sowieso wegoptimiert wird 😃 🙂



  • Ist dasselbe wie bei mir. 🙄



  • &array[size] ist OK, dafür gibt's ne extra Ausnahme im Standard. Ohne die könnte man keine halb-offenen Zeiger Intervalle bilden, und das wäre ziemlich lästig.

    &array[size + 1] ist nicht OK, weil man - abgesehen von der "one past last element" Ausnahme oben und NULL - nur Zeiger auf gültige Objekte bilden darf.



  • hustbaer schrieb:

    &array[size] ist OK, dafür gibt's ne extra Ausnahme im Standard. Ohne die könnte man keine halb-offenen Zeiger Intervalle bilden, und das wäre ziemlich lästig.

    Könnte man schon, doch eben durch array + size , aber du hast recht.

    hustbaer schrieb:

    &array[size + 1] ist nicht OK, weil man - abgesehen von der "one past last element" Ausnahme oben und NULL - nur Zeiger auf gültige Objekte bilden darf.

    Das leuchtet ein 🙂



  • Könntest du noch die entsprechenden Zitate bringen? 🙂



  • Sone schrieb:

    hustbaer schrieb:

    &array[size] ist OK, dafür gibt's ne extra Ausnahme im Standard. Ohne die könnte man keine halb-offenen Zeiger Intervalle bilden, und das wäre ziemlich lästig.

    Könnte man schon, doch eben durch array + size , aber du hast recht.

    Mah h4x0r, du klugscheißen-ohne-nachdenken-Mensch, für dein "könnte man doch" gilt die selbe Ausnahme. Und würd's die von hustbaer erwähnte Ausnahme nicht geben wär deins genauso Standardwidrig. 🙄



  • Swordfish schrieb:

    Sone schrieb:

    hustbaer schrieb:

    &array[size] ist OK, dafür gibt's ne extra Ausnahme im Standard. Ohne die könnte man keine halb-offenen Zeiger Intervalle bilden, und das wäre ziemlich lästig.

    Könnte man schon, doch eben durch array + size , aber du hast recht.

    Mah h4x0r, du klugscheißen-ohne-nachdenken-Mensch, für dein "könnte man doch" gilt die selbe Ausnahme. Und würd's die von hustbaer erwähnte Ausnahme nicht geben wär deins genauso Standardwidrig. 🙄

    Wieso zum Teufel ist array + size UB ohne Ausnahme!? Das ist doch einfach ein erhöhter Zeiger.



  • Du hast doch selbst gesagt, es leuchte ein, dass &array[size + 1] nicht erlaubt ist -- und das ist das selbe wie array + size + 1



  • ubububububububub schrieb:

    Du hast doch selbst gesagt, es leuchte ein, dass &array[size + 1] nicht erlaubt ist -- und das ist das selbe wie array + size + 1

    Nicht direkt.
    &array[size + 1] ist laut Standard dasselbe wie &(*(array + (size + 1))). Und da steckt halt die Dereferenzierung eines wilden Pointers drinnen.


  • Mod

    Ich bin ziemlich sicher, dass der Standard keine "wilden Zeiger" kennt.



  • Swordfish schrieb:

    Ich weiß nicht, wie's der Standard damit hält, aber kein Compiler wird bei

    array[ sonstwas ];
    

    dereferenzieren. Wofür denn auch?

    Um auf das Element zuzugreifen. array[index] ist nur eine andere Schreibweise für *(array+index) .

    Bisher hat niemand ein Argument dafür geliefert, warum es dem Compiler verboten sei, bei &array[index] zu dereferenzieren. Das kann nämlich selbst bei gültigem Index eine Rolle spielen.

    Sone schrieb:

    &array[size + 1] ist laut Standard dasselbe wie &(*(array + (size + 1))). Und da steckt halt die Dereferenzierung eines wilden Pointers drinnen.

    Nicht nur die Dereferenzierung, auch das Lesen eines Zeigers jenseits des Arrays ist UB -- bis auf die von hustbaer genannte Ausnahme.

    < 💡 >



  • glühbirne schrieb:

    Swordfish schrieb:

    Ich weiß nicht, wie's der Standard damit hält, aber kein Compiler wird bei

    array[ sonstwas ];
    

    dereferenzieren. Wofür denn auch?

    Um auf das Element zuzugreifen. array[index] ist nur eine andere Schreibweise für *(array+index) .

    Du hast nichts verstanden. Eine Anweisung wie diese hat keinen Effekt, weil sie überhaupt nichts tut. Es gibt keine Berechnung o. ä., für die der Dereferenzierte Wert gebraucht wird. Es wird einfach rausoptimiert, alles andere wäre Wahnsinn.

    glühbirne schrieb:

    Sone schrieb:

    &array[size + 1] ist laut Standard dasselbe wie &(*(array + (size + 1))). Und da steckt halt die Dereferenzierung eines wilden Pointers drinnen.

    Nicht nur die Dereferenzierung, auch das Lesen eines Zeigers jenseits des Arrays ist UB -- bis auf die von hustbaer genannte Ausnahme.

    Danke 👍



  • Sone schrieb:

    Du hast nichts verstanden. Eine Anweisung wie diese hat keinen Effekt, weil sie überhaupt nichts tut. Es gibt keine Berechnung o. ä., für die der Dereferenzierte Wert gebraucht wird. Es wird einfach rausoptimiert, alles andere wäre Wahnsinn.

    Ne, wie üblich hast du nichts verstanden.

    So eine Optimierung ist Qualität der Implementierung, der C++-Standard schreibt sie nicht vor.

    < 💡 >



  • hustbaer schrieb:

    &array[size + 1] ist nicht OK, weil man - abgesehen von der "one past last element" Ausnahme oben und NULL - nur Zeiger auf gültige Objekte bilden darf.

    Moment, das würde ja heißen, dass dieses Programm eigentlich nicht standardkonform wäre 😮:

    #include <iostream>
    #include <ostream>
    int main()
    {
      int const* const Zgr_F = reinterpret_cast<int*>(0x0); //Var. 1
      int const* const Zgr_W = reinterpret_cast<int*>(0xF2A911E); //Var. 2
        //So, beide Zeiger dürften ins Nichts zeigen
      int const Y = 20;
      int const* Zgr_M = &Y + 7372; //Var. 3
        //Und auch dieser zeigt wohl irgendwohin
      std::cout << Zgr_F << Zgr_W << Zgr_M << std::endl;
        //Gegen das Wegoptimieren
    }
    

    Ich hoffe jetzt mal, dass hattest du irgendwie anders gemeint …



  • Eben, genau das hab ich mich auch gefragt.


Anmelden zum Antworten