Random-Access-Iteratoren über das ende des Bereiches hinaus Vergleichen
-
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]oderv.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
falsezurückliefern (bzw.truewenn ein Overflow aufgetreten ist).
Es ist nichts weiteres als Skalararithmetik mit Zeigern. Darf ich denn den Zeiger zu einem Skalar casten (perreinterpret_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.
-
pragma ticker schrieb:
Mit dem intptr_t (hab vergessen wie der genau heisst) kannst du keine Pointerarithmetik betreiben.
Wieso nicht? Dürfen wir auf einmal nicht einmal mehr mit gewöhnlichen
ints so hantieren wie wir wollen?auto scalar = reinterpret_cast<std::uintptr_t>(array_anfang); scalar += beliebig; // Kein UB, ich darf Späße treiben wie ich lustig bin // ...