Du bist nicht angemeldet.

Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!

Werbeanzeige

1

30.03.2015, 01:53

Warum werfen std iteratoren keine Exception

Guten Abend,

wie im Titel zu sehen ist, frage ich mich allmählich, warum die std Iteratoren keine exception werfen, wenn man auf einen ungültigen Index verweist?
Sie checken zwar ob sie richtig sind, aber sie nutzen eben nur asserts. Gibt es dafür einen plausiblen Grund?
Ich könnte mir zwar um solche Iteratoren eine Klasse bauen und diese dann an benutzen, aber wirklich sauber ist das nicht.
Oder übersehe ich generell etwas?

mfg

2

30.03.2015, 02:02

Ich glaube die iteratoren füren die checks nur im debug modus aus, denn wie alles bei C++ ist ein ungültiger iterator undefiniertes verhalten ;)

4

30.03.2015, 03:36

Dumdidum, bringt mich nicht weiter, wenn ich exceptions fangen will. Außerdem steht da auch keine Antwort auf meine Frage.

Frage richtig gelesen in einer Minute...

BlueCobold

Community-Fossil

Beiträge: 10 738

Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer

  • Private Nachricht senden

5

30.03.2015, 06:31

Es steht doch alles in den Links. Wenn Du Exceptions willst, tu was da steht. Deine Frage nach dem "warum" ist damit obsolet, denn sie tun es, wenn man es richtig anstellt. Du hast also die Wahl.
Ich wüsste allerdings nicht, wieso genau man Exceptions haben will bei Iteratoren. Werfen Iteratoren einen Fehler, wäre es natürlich gut, das sofort während der Entwicklung zu merken. Der beste Weg dafür ist eine Assertion. Wie eigentlich immer, ist es in der Entwicklung besser, dass das Programm harte Fehler wirft, statt dass eventuell Bugs weg-gecatcht werden, die man eigentlich fixen sollte.
Teamleiter von Rickety Racquet (ehemals das "Foren-Projekt") und von Marble Theory

Willkommen auf SPPRO, auch dir wird man zu Unity oder zur Unreal-Engine raten, ganz bestimmt.[/Sarkasmus]

Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von »BlueCobold« (30.03.2015, 06:37)


Databyte

Alter Hase

Beiträge: 1 040

Wohnort: Na zu Hause

Beruf: Student (KIT)

  • Private Nachricht senden

6

30.03.2015, 08:01

Wieso sollte ein Iterator prüfen ob er gültig ist? Wenn du vernünftig programmierst, wird er eben nie ungültig.
Zu verlangen, dass die Iteratoren jedesmal Zeit aufwenden, um zu prüfen ob sie noch gültig sind, wenn sich ihre Gültigkeit auch einfach aus deiner Programmierung ergibt, ist mehr so eine Java-Sache :P
In der C++ Doku ist überigens auch für jede Funktion eines Containers angegeben, in wie fern sie die Gültigkeit der Iteratoren verändert (siehe zum Beispiel std::vector::push_back).

Es gibt natürlich auch Anwendungen wo eine Überprüfung sinnvoll ist. Zum Beispiel in einem Parser. Aber dann ist es meistens sauberer eine eigenen Iterator + Exception zu definieren.

Evrey

Treue Seele

Beiträge: 245

Beruf: Weltherrscher

  • Private Nachricht senden

7

30.03.2015, 13:00

Gut, der Debug-Mode, der - wie der Name verrät - nur zum Debuggen geeignet ist, fügt Bounds Checking usw. hinzu. Das ändert jedoch nichts daran, dass die Standard-Iteratoren oftmals/immer(?) keine Exceptions werfen. Der Grund dafür ist einfach: Um die STL schlank und möglichst schnell zu halten, wurden Iteratoren so konzipiert, dass jeder Pointer ein gültiger Iterator ist. Und wer schon öfters mal Typ-Fehler mit Templates hatte, konnte gelegentlich sehen, dass viele Iteratoren, vor allem von std::vector, auch tatsächlich als simple Pointer umgesetzt wurden.

Und Pointer werfen nunmal keine Exceptions. Sie geben dir höchstens SIGSEGV oder Access Violation. Wie BlueCobold schrieb, ist es hier sinnvoll, Assertions einzusetzen. Wahlweise auch welche, die im Release-Modus noch drin sind. Das Programm stürzt dann zwar auch ab, wenn ein Fehler passiert, aber wenigstens kannste dich dabei mit vielen Informationen anreichern, die dir ein "normaler" Crash nicht liefert. Etwa Datei und Zeilennummer.

Assertions sind eigentlich fast immer gut, aber sie ersetzen keines Wegs besser durchdachten Code. Wenn du dir nicht sicher bist, ob dein Iterator eines, z.B., std::vectors später mal noch gültig ist, wenn du ihn brauchst, dann sind Iteratoren nicht das Werkzeug, mit dem du arbeiten sollst. Iteratoren sind dazu da, sofort verwendet zu werden. Nutze statt dessen Indices oder Keys. Wenn du z.B. immer das siebte Element krallen willst, greifste dir später einfach my_vector[7]. Und wenn du dir nichtmals sicher bist, ob der Index noch innerhalb des Wertebereichs des std::vectors liegt, dann nutze eben my_vector.at(7), das eine Exception wirft, sobald der Index Murks ist.

C-/C++-Quelltext

1
2
3
4
int main(int _argc, char** _argv) noexcept {
  asm volatile("lock cmpxchg8b %eax");
  return 0;
} // ::main
(Dieses kleine Biest vermochte einst x86-Prozessoren lahm zu legen.)

=> Und er blogt unter Hackish.Codes D:

dot

Supermoderator

Beiträge: 9 757

Wohnort: Graz

  • Private Nachricht senden

8

30.03.2015, 13:12

Ich vermute, was du eigentlich willst, ist nicht C++ exceptions fangen, sondern dem Betriebssystem einen Crashhandler geben, um im Falle eines Programmabsturzes noch irgendwelche Informationen zu sammeln, bevor der Prozess gewiped wird!?

9

30.03.2015, 13:54

@Evrey: Danke für die Erklärung. Das eine explizite Abfrage natürlich ein bisschen Overhead produziert, und man diesen mit iteratoren möglichst klein halten möchte, leuchtet ein.

Es ging mir bei der ganzen Frage nicht um ein bestimmtes Problem beim Coden, ich hätte sonst durchaus ein Beispiel gepostet. Es stellte sich mir die Frage, warum eben lieber asserts statt exceptions genutzt werden. Aber Evrey hat es ja ganz gut erklärt.

Nox

Supermoderator

Beiträge: 5 272

Beruf: Student

  • Private Nachricht senden

10

30.03.2015, 19:29

Wie in den von mir geposteten Links zu lesen ist, braucht man das nicht selber von Hand zu machen bei den STL containern. Man kann die entsprechenden Überprüfungen (auch für den Release!) aktivieren. Es wird auch genau genannt in welchen Fällen die zusätzlichen Überprüfungen greifen (für VC). Man kann aber natürlich auch alles gerne selber machen.
Schade nur, dass es anscheinend notwendig ist solche Informationen explizit nochmal zu betonen, wenn doch ein einfaches Überfliegen der Links helfen würde.
PRO Lernkurs "Wie benutze ich eine Doku richtig"!
CONTRA lasst mal die anderen machen!
networklibbenc - Netzwerklibs im Vergleich | syncsys - Netzwerk lib (MMO-ready) | Schleichfahrt Remake | Firegalaxy | Sammelsurium rund um FPGA&Co.

Werbeanzeige