Random-Access-Iteratoren über das ende des Bereiches hinaus Vergleichen


  • Mod

    Ein Container mit N Elementen verfügt über genau N+1 gültige Iteratoren.



  • otze schrieb:

    Sone: wenn du auf die category anspielst: i+=3 macht deutlich, dass es sich um randomaccess iteratoren handeln _muss_.

    Oder das Topic ...



  • Wenn es sich beim Container um std::vector handelt, kannst du auch einfach Pointer benutzen. Ansonsten verrate uns doch einfach deinen Random-Access-Container!



  • knivil schrieb:

    Wenn es sich beim Container um std::vector handelt, kannst du auch einfach Pointer benutzen.

    In der Praxis schon, nach den Standardfuzzis hier nicht.

    Was gehen dürfte ist

    assert(foo.size() < numeric_limits<size_t>::max() - 3);
    for (size_t i = 0; it < foo.size(); i += 3) {
      auto& val = foo[i];
    }
    


  • In der Praxis schon, nach den Standardfuzzis hier nicht.

    Welche Standardfuzzis? Mit Zeigern ist das völlig in Ordnung - natürlich wenn man explizit welche nutzt (via &v[0] oder v.data() ).



  • Sone schrieb:

    In der Praxis schon, nach den Standardfuzzis hier nicht.

    Welche Standardfuzzis? Mit Zeigern ist das völlig in Ordnung

    Wie kommst du darauf? Für Zeiger gelten ähnliche Beschränkungen, nur nicht auf den Container, sondern konkret auf das Objekt bezogen. Was genau das ist -- keine Ahnung, ob man das irgendwo exakt nachlesen kann, aber es dürfte ein Array der Größe capacity() sein.



  • Du darfst den Zeiger nur nicht dereferenzieren, Zeigerarithmetik wie hier gebraucht ist beliebig erlaubt.



  • 5.7p5 sagt undefined.



  • Sone schrieb:

    In der Praxis schon, nach den Standardfuzzis hier nicht.

    Welche Standardfuzzis? Mit Zeigern ist das völlig in Ordnung

    Mit Standardfuzzis sind Leute gemeint, die den Standard verstehen und nicht wilde Spekulationen darüber anstellen.

    Du bist ein Pseudo-Standardfuzzi.



  • man darf also nicht schreiben

    for (auto it = v.begin(); it != v.end(); it += 3)
    

    ? Auch nicht bei std::vector?



  • Nein.



  • ghjghjghj schrieb:

    man darf also nicht schreiben

    for (auto it = v.begin(); it != v.end(); it += 3)
    

    ? Auch nicht bei std::vector?

    Warum willst du das auch machen?
    ändere doch einfach die Abbruchbedingung.



  • Nathan schrieb:

    Warum willst du das auch machen?

    Dürfte offensichtlich sein: Einfacherer Code.



  • Nein, ich mein:
    Was will er mit einem Iterator, der hinter end() zeigt?
    Ich mein, selbst testen, ob der gültig ist, ist undefiniert, oder?



  • Nexus schrieb:

    Nathan schrieb:

    Warum willst du das auch machen?

    Dürfte offensichtlich sein: Einfacherer Code.

    Es sind die obskursten Dinge in C++ erlaubt. Wieso sollte da etwas so simples wie

    If both the pointer operand and the result point to elements of the same array object, or one past the last element of the array object, the evaluation shall not produce an overflow; otherwise, the behavior is undefined.

    nicht erlaubt sein...?* Aber offensichtlich ist das so. Merkwürdig. Danke Bashar, das wusste ich nicht - recht unintuitiv.

    ändere doch einfach die Abbruchbedingung.

    👍
    Es wird aber auch so zu kompliziert.

    *: Die Aussage lässt sich auch anders interpretieren, aber das wäre weit hergeholt.



  • Nathan schrieb:

    Was will er mit einem Iterator, der hinter end() zeigt?

    Er will ja keinen Iterator, der hinter end() zeigt, sondern über jedes dritte Element iterieren. Und mit dem naheliegendsten Code (wie man ihn von Ganzzahlen-Iterationen kennt) kommt eben UB zustande.

    Sone schrieb:

    Wieso sollte da etwas so simples wie [...] nicht erlaubt sein?

    Weil man dadurch die Implementierung zwingen würde, realitätsferne Fälle richtig zu behandeln, möglicherweise auf Kosten der normalen Benutzung.



  • Weil man dadurch die Implementierung zwingen würde, realitätsferne Fälle richtig zu behandeln, möglicherweise auf Kosten der normalen Benutzung.

    Was muss die Implementierung denn machen, wenn ich einfach einen Zeiger mit einem Skalar addiere? Sie muss einfach brav die Addition durchführen und beim Vergleich in der Abbruchbedingung false zurückliefern (bzw. true wenn ein Overflow aufgetreten ist).
    Es ist nichts weiteres als Skalararithmetik mit Zeigern. Darf ich denn den Zeiger zu einem Skalar casten (per reinterpret_cast ) und diesen dann mit einem anderen Skalar addieren sodass ich eine Abbruchbedingung erstellen kann die kein UB ist? Natürlich. Mit Zeigern darf man nicht, weil ...?



  • Okay, dann eben keine Pointer sondern ein Index.

    5.7p5 sagt undefined.

    Ich tippe mal auf den von Sone zitierten Test:

    If both the pointer operand and the result point to elements of the same array object, or one past the last element of the array object, the evaluation shall not produce an overflow; otherwise, the behavior is undefined.

    D.h. wenn meine Zeigeroperation keinen Ueberlauf produziert, dann ist alles im gruenen Bereich?



  • Sone schrieb:

    Es ist nichts weiteres als Skalararithmetik mit Zeigern. Darf ich denn den Zeiger zu einem Skalar casten (per reinterpret_cast ) und diesen dann mit einem anderen Skalar addieren sodass ich eine Abbruchbedingung erstellen kann die kein UB ist? Natürlich.

    Natürlich nicht.

    Mit dem intptr_t (hab vergessen wie der genau heisst) kannst du keine Pointerarithmetik betreiben.



  • D.h. wenn meine Zeigeroperation keinen Ueberlauf produziert, dann ist alles im gruenen Bereich?

    Eben das meinte ich mit 'anders interpretieren'. Das wäre aber wie gesagt weit hergeholt.
    Oder nicht? Ich bin verunsichert.


Anmelden zum Antworten