kann ich mich darauf verlassen, dass ein container sich gegen indexüberschreitung absichert?
-
nehmen wir mal an, dass ich folgende Klasse habe:
class Foo{ private: std::vector<int> vector; public: //... int& operator[](std::size_t n){ return vector[n] } };kann ich mich nun drauf verlassen, dass im op[] des vectors bei indexüberschreitung im debugmodus ein assert kommt, oder muss ich jedes mal selber den assert schreiben?
-
Ein assert kommt gar nicht, aber wenn du statt [] at() verwendest, kommt eine Exception.
-
Der op[] hat IIRC kein assert drin, nur at prüft den Bereich.
-
autsch, ganz vergessen, dass es ein at() gibt
. Dann ist die antwort klar, danke euch.
-
Walli schrieb:
Der op[] hat IIRC kein assert drin, nur at prüft den Bereich.
Ob der op[] ein assert verwendet oder nicht ist nicht definiert. Der op[] hat undefiniertes Verhalten, wenn der Index "out of range" ist. D.h. aber nicht automatisch, dass gute Implementationen sowas nicht anzeigen. Man kann sich aus Sicht des Standards nur nicht auf irgendwas verlassen - es kann alles passieren.
-
hätten die ruhig in den standart reinschreiben können das ein assert pflicht ist

-
Es gibt STL implementierungen, die im Debugmodus solche checks auch für [] machen. Ich glaube STLPort ist eine solche. Die machen dann auch noch andere Checks.
-
HumeSikkins schrieb:
Walli schrieb:
Der op[] hat IIRC kein assert drin, nur at prüft den Bereich.
Ob der op[] ein assert verwendet oder nicht ist nicht definiert. Der op[] hat undefiniertes Verhalten, wenn der Index "out of range" ist. D.h. aber nicht automatisch, dass gute Implementationen sowas nicht anzeigen. Man kann sich aus Sicht des Standards nur nicht auf irgendwas verlassen - es kann alles passieren.
wieso hat man sich denn bei der standartisierung dafür entschieden? eben weil es at() gibt? Oder hat man damals nicht absehen können, dass der op[] so "selbstverständlich" genutzt werden wird?
-
otze schrieb:
HumeSikkins schrieb:
Walli schrieb:
Der op[] hat IIRC kein assert drin, nur at prüft den Bereich.
Ob der op[] ein assert verwendet oder nicht ist nicht definiert. Der op[] hat undefiniertes Verhalten, wenn der Index "out of range" ist. D.h. aber nicht automatisch, dass gute Implementationen sowas nicht anzeigen. Man kann sich aus Sicht des Standards nur nicht auf irgendwas verlassen - es kann alles passieren.
wieso hat man sich denn bei der standartisierung dafür entschieden? eben weil es at() gibt? Oder hat man damals nicht absehen können, dass der op[] so "selbstverständlich" genutzt werden wird?
Ich weis zwar nicht wirklich warum, aber ich denke mir mal das man die Variante die einem Array am meisten ähnelt nicht langsamer machen wollte. Denn ein "normales" Array macht auch keinen range-check. Ausserdem kann es auch vorkommen das man selbst solche range checks irgendwo vorher ausführt warum sollte der Container diese dann noch einmal checken? Wenn man einen range-check haben will benutzt man halt at() und wenn man keinen haben will operator[]
Das ist das was ich darüber denke, ich weis nicht ob das auch so richtig ist. ( nur so als Disclaimer
)
-
ich denke, das die Geschwindigkeit kein argument ist, da "assert" im release modus durch " " ersetzt wird, im endprodukt merkt man davon also nichts mehr.
-
Hallo,
Stichwort: zero-cost principle oder you don't pay for what you don't use.
Der Operator[] ist so spezifiziert, dass er keine zusätzlichen Kosten (im Vergleich zu einem eingebauten Array) hat. So kann der Raw-Performance-Junky ohne Probleme den Op[] benutzen und der, der Checks haben will kann eine Schicht auf die vorhandene draufsetzen.
Eine Schicht wegzunehmen ist hingegen viel schwerer.Und wie Ponto ja bereits angedeutet hat, bieten moderne STL-Implementationen im Debug-Modus vielmehr als nur Range-Checks.
ich denke, das die Geschwindigkeit kein argument ist, da "assert" im release modus durch " " ersetzt wird, im endprodukt merkt man davon also nichts mehr.Sowas wie einen Release-Modus gibt es aus Sicht des Standards nicht. Es gibt nur die Möglichkeit das Makro NDEBUG zu definieren, und damit asserts zu noops zu machen. Da diesees Makro aber explizit gesetzt werden muss, würde der Default-Fall damit dem zero-cost-Principle widersprechen.