Entwickler-Ecke

Algorithmen, Optimierung und Assembler - goTos wie Break und Exit stellen Sicherheitslücke dar?


Hidden - Sa 05.04.08 13:02
Titel: goTos wie Break und Exit stellen Sicherheitslücke dar?
Hi,

Bisher habe ich in verschieden Themen gelesen, dass die o.ä. GoTo ruhig mal zu Beginn von Prozeduren bei Abbruchbedingungen(Exit), bzw. bei Suchschleifen(for) nach Fund, verwendet werden dürfen. Selbstverständlich gut kommentiert.

Mein Lehrer meinte jetzt aber letztens, jedes GoTo stelle eine Sicherheitslücke im Programm dar :shock: und die o.ä. seien GoTo zum Ende der Prozedur/Schleife.

Wie seht ihr das, was habt ihr da gelernt und was ist dran?

mfG,


Yogu - Sa 05.04.08 13:08

Hallo,

wenn du mal das CPU-Fenster von Delphi anschaust und per F8 die Befehle durchgehst, wirst du schnell eins bemerken: Der Code steckt voller Sprünge. Andauernd ladet man wo anders - das können nur Gotos sein. Wenn das eine Sicherheitslücke ist, dann wäre Delphi eine komplett unsichere Sprache.

Und wenn du mal selber etwas Assembler angeschaut hast, dann siehst du auch, dass es gar nicht ohne Sprünge geht. Es gibt eigentlich keine Möglichkeit, ohne Sprünge zu arbeiten. Delphi macht das ganze für dich, du bekommst da gar nichts mit. Jede Funktion oder Prozedur, jede IF-Verschachtelung und jede CASE-Anweisung, wie soll das denn anders gehen? Da stecken überall Sprünge dahinter.

Vielleicht meint dein Lehrer, dass unter Umständen Variablen nicht gesetzt sein können, oder sonst irgendwas falsch gemacht werden kann. Aber solche Situationen kommen andauernd - man muss halt aufpassen und genug Fehlerbehandlungen einbauen.

(Anmerkung: Ich hab kein Informatik, daher auch keinen Leher in der Richtung)

Grüße,
Yogu


Hidden - Sa 05.04.08 13:29

Hi,

Ersteinmal danke für die schnelle Antwort!
Gut, und kann man die zwei o.e. Lösungen als sauber bezeichnen oder ist break/exit generell unsauber?

Edit:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
procedure dosomething;
begin
  if not myBoolean then Exit;
  {langer Prozedurequelltext, der sonst hier ins else müsste(bzw. not else -> hauptteil)}
end;

function search(aSearchFor: Variable): Variable;
var
  i: Integer;
begin
  for k := 0 to LimitI do
    if ... then beign
      ...
      Break;
    end;
end;


Der Vorschlag meines Lehrers im letzten Teil wäre eine While-Schleife mit inc(i) und Abbruchbedingung (i > limitI) or found. [OT]ist der Unterschied zwischen for- und While nicht, dass sich for besser optimieren lässt(Prozessor-Laufvariable)? [/OT]

Wieauchimmer, lässt sich durch Break/Exit Laufzeit spaaren?

mfG,


Yogu - Sa 05.04.08 13:41

user profile iconHidden hat folgendes geschrieben:
kann man die zwi o.ä. Lösungen als sauber bezeichnen oder ist break/exit generell unsauber?

Das weikß ich jetzt nicht mehr. Aber manchmal ist es doch unumgänglich: Bei einer for, wenn plötzlich auf "Abbrechen" geklickt wurde. Wie soll man da ohne Break oder Exit wieder rauskommen?


BenBE - Sa 05.04.08 13:43

o.ä. = oder ähnliches ??? Oder meinst Du o.e. (oben erwähnte)???

Break und Exit sind oftmals nützlich, können aber in Einzelfällen dazu führen, dass das Programm dadurch unübersichtlicher wird, gerade dadurch, dass der normale Programmfluss geändert wird. Ein Sicherheitsrisiko per se sind diese beiden Befehle nicht; nur, wenn sie in die Hände schlampiger Programmierer geraten ...


Hidden - Sa 05.04.08 13:49

user profile iconBenBE hat folgendes geschrieben:
o.ä. = oder ähnliches ??? Oder meinst Du o.e. (oben erwähnte)???

:oops: Ja
user profile iconBenBE hat folgendes geschrieben:
Break und Exit sind oftmals nützlich, können aber in Einzelfällen dazu führen, dass das Programm dadurch unübersichtlicher wird

Jo, wie gesagt:
user profile iconHidden hat folgendes geschrieben:
Selbstverständlich gut kommentiert.

mfG,


Delete - Sa 05.04.08 14:29

user profile iconBenBE hat folgendes geschrieben:
diese beiden Befehle nicht; nur, wenn sie in die Hände schlampiger Programmierer geraten ...

In Händen von schlampigen Programmierern ist alles eine Sicherheitslücke. ;)


Delete - Sa 05.04.08 16:31

user profile iconHidden hat folgendes geschrieben:
Hi,

Ersteinmal danke für die schnelle Antwort!
Gut, und kann man die zwei o.e. Lösungen als sauber bezeichnen oder ist break/exit generell unsauber?

Edit:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
procedure dosomething;
begin
  if not myBoolean then Exit;
  {langer Prozedurequelltext, der sonst hier ins else müsste(bzw. not else -> hauptteil)}
end;

function search(aSearchFor: Variable): Variable;
var
  i: Integer;
begin
  for k := 0 to LimitI do
    if ... then beign
      ...
      Break;
    end;
end;


ja, das ist eine unsaubere programmierung. in der strukturierten programmierung wirst du codekonstrukte al'la goto, break, exit auch gar nicht finden. dort sind die routinen so aufzubauen, dass sie sauber den jeweiligen codeblock verlassen.

im übrigen, gibts ja nur zwei möglichkeiten zu springen, bedingt und unbedingt. von den schleifen gibts auch nur zwei typen, die kopf- und die fussgesteuerten. vom compiler werden sie mit bedingten oder unbedingten sprunganweisungen umgesetzt. dies heisst jedoch nicht, dass das auf der quellcodeebene auch sein sollte. ganz im gegenteil. damit der compiler sauber arbeiten kann, braucht er ordentliche strukturen, und da kommt er teilweise mit den oben genannten controllkonstruktren durcheinander. daher mein tipp, möglichst vermeiden und wenn dann nur gewählt einsetzen... sonst kommen leicht nächtelange debuggingsessions auf dich zu, wo die fehler nur schwer zu lokalisieren sind.

PS: ebenfalls ist die EXCEPTION ein tötliches konstrukt, welches nur in absoluten ausnahmen eingesetzt werden sollte. mit der strukturierten programmierung hat dies gar nix zu tun.

<HTH> GG

PS: weshalb nicht so umsetzen:


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
procedure dosomething;
begin
  if myBoolean then 
  begin
    {langer Prozedurequelltext, der sonst hier ins else müsste(bzw. not else -> hauptteil)}
  end;
end;

function search(aSearchFor: Variable): Variable;
var
  i: Integer;
begin
 k := 0;
 while (k <= limitI) and ... do
 begin

  inc(k);
 end;


Der Compiler macht ja nix anderes draus...


Delete - Sa 05.04.08 16:44

user profile iconGrenzgaenger hat folgendes geschrieben:
PS: ebenfalls ist die EXCEPTION ein tötliches konstrukt, welches nur in absoluten ausnahmen eingesetzt werden sollte. mit der strukturierten programmierung hat dies gar nix zu tun.

Kannst du das Begründen und mit Beispielen untermauern? Ich sehe das nämlich etwas anders. Und wenn es tödlich wäre, dann müsste es mittlerweile schon unzähliche tote Programme geben.


AHT - Sa 05.04.08 17:14
Titel: Re: goTos wie Break und Exit stellen Sicherheitslücke dar?
user profile iconHidden hat folgendes geschrieben:


Mein Lehrer meinte jetzt aber letztens, jedes GoTo stelle eine Sicherheitslücke im Programm dar :shock: und die o.ä. seien GoTo zum Ende der Prozedur/Schleife.

Wie seht ihr das, was habt ihr da gelernt und was ist dran?



Mmh... - frage deinen Lehrer mal, wo genau da die Sicherheitslücke sein soll. Im Prinzip dürfte das, wie vieles andere auch, als OP-Code in Jump- oder Returnbefehlen enden.

Was ich gelernt habe - ist aber schon zwanzig Jahre her:
GOTOs machen den Code unübersichtlichg. Hat dein Lehrer da andere Infos, würde mich das sehr interessieren. Lehrer sind doch dafür da, einem etwas zu erklären - und zwar so, dass man das auch versteht. Löchere den doch mal ein bischen...


Hidden - Sa 05.04.08 17:41

Hi,

angenommen, ich habe einen Code folgender Form:


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
procedure doSomeThing(X, Y, Z: Integer);
begin
  try
    if myArray[X, Y, Z] then Exit;  //der Einfachheit halber ein Array of Boolean
  except //unzulässige Indizes ignorieren
  end;
  //eigentlicher Prozedurtext
end;



[OT]
Eigentlich geht es um ein Schachprogramm. Um herauszufinden, ob ein König im Schach steht, gehe ich alle Richtungen vom König aus in for-Schleifen durch und checke beim Finden einer Figur, ob es sich um eine Figur handelt, die aus dieser Richtung Schach geben kann. Wenn ja, kommt ein Exit(vorher habe ich result auf false(kein Schach) gesetzt). Ansonsten kommt ein Break, da aus dieser Richtung keine andere Figur mehr Schach geben kann.

Die Springer muss ich seperat betrachten, da sie nicht aus einer der acht Richtungen vom König aus Schach geben. nun checke ich einfach, ob auf den Feldern mit den Positionen (+2/+1)usw... feindliche Springer stehen. Diese Indizes können außerhalb des Feldes(2D-Array) liegen.

Nun wären für mich drei Lösungen möglich: a)Feld größer machen und außen mit nil füllen. b) Indizes einzeln auf Validität prüfen c) try und bei Except ignorieren.

Sry für ein so langes OT, sollte es zu dem Beispiel fragen geben, bitte über PM nachdenken.
[/OT]

mfG,


Delete - Sa 05.04.08 18:57

user profile iconHidden hat folgendes geschrieben:
c) try und bei Except ignorieren.

Wozu dann einen try-except-Block, wenn du die Exception doch ignorierst? So soll man ja Exceptions auch nicht verwenden. :roll:


Silas - Sa 05.04.08 18:57

user profile iconGrenzgaenger hat folgendes geschrieben:
in der strukturierten programmierung wirst du codekonstrukte al'la goto, break, exit auch gar nicht finden. dort sind die routinen so aufzubauen, dass sie sauber den jeweiligen codeblock verlassen.

Wenn du beispielsweise ein Array durchsuchst, kommst du um ein Break gar nicht herum (es sei denn, du NOPst dich durch die restlichen Durchläufe).

user profile iconGrenzgaenger hat folgendes geschrieben:
PS: ebenfalls ist die EXCEPTION ein tötliches konstrukt, welches nur in absoluten ausnahmen eingesetzt werden sollte. mit der strukturierten programmierung hat dies gar nix zu tun.

Das stimmt auf jeden Fall nicht. Bei einer Exception werden alle kritischen, vom Compiler vorgenommenen Aktionen rückgängig gemacht (siehe z.B. Stack-Unwinding).

Exit zu vermeiden, ist in den meisten Fällen sinvoll, wenn man allerdings ein begin-end-Konstrukt über die ganze Prozedur vermeiden kann, macht die Verwendung Sinn.


Yogu - Sa 05.04.08 19:24

user profile iconSilas hat folgendes geschrieben:
Wenn du beispielsweise ein Array durchsuchst, kommst du um ein Break gar nicht herum (es sei denn, du NOPst dich durch die restlichen Durchläufe).

Warum nicht so, wie user profile iconGrenzgaenger vorgeschlagen hat?

user profile iconGrenzgaenger hat folgendes geschrieben:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
function search(aSearchFor: Variable): Variable;
var
  i: Integer;
begin
 k := 0;
 while (k <= limitI) and ... do
 begin

  inc(k);
 end;


Silas - Sa 05.04.08 19:43

user profile iconYogu hat folgendes geschrieben:
Warum nicht so, wie user profile iconGrenzgaenger vorgeschlagen hat?

Stimmt, das wäre eine Möglichkeit, allerdings denke ich das das spätestens dann unübersichtlich wird, wenn man für die Bedingung zusätzliche Variablen einführen muss. Und ein Break am Ende eines if-Blocks ist IMHO wirklich sauber.


alzaimar - Sa 05.04.08 22:05

Sauber ist das, was verständlich ist.

user profile iconHidden hat folgendes geschrieben:
Der Vorschlag meines Lehrers im letzten Teil wäre eine While-Schleife mit inc(i) und Abbruchbedingung (i > limitI) or found

Und was ist bei vielen verschachtelten Schleifen? Soll man das 'found' dann mitschleppen? Hier zwei Fragmente.

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
i := 0;
  While (i<10and not found Do Begin
  k := 0;
  while (k<100and not found Do Begin
    j := 0;
    while (j<50and not found Do Begin
      ...
      if StopTheLoops (i,j,k) Then found := True;
    End
  End
End

oder

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
For i:=0 to 9 do
  For k:=0 to 99 do
    For j := 0 to 49 do begin
      ...
      if StopTheLoops (i,j,k) Then Goto DoneLoop;
    End;

DoneLoop: 
 ...

Was ist denn nun 'sauber' im Sinne von 'Klar, Verständlich und Einfach'?
Eine Prämisse der Programmierung ist doch, unnötige Konstrukte zu vermeiden und den Code so klar, einfach und verständlich wie möglich zu gestalten. Das sollte der Lehrer gegen das Dogma "Alle Gotos, Breaks und Exits sind verböten" abwägen.
user profile iconGrenzgaenger hat folgendes geschrieben:
in der strukturierten programmierung wirst du codekonstrukte al'la goto, break, exit auch gar nicht finden. dort sind die routinen so aufzubauen, dass sie sauber den jeweiligen codeblock verlassen.

Nein, das ist Quatsch, wenn es im Widerspruch zur obersten Regel (s.o.) steht.
user profile iconGrenzgaenger hat folgendes geschrieben:

PS: ebenfalls ist die EXCEPTION ein tötliches konstrukt, welches nur in absoluten ausnahmen eingesetzt werden sollte. mit der strukturierten programmierung hat dies gar nix zu tun.

Blödsinn. Wieso findet man Exceptions NUR bei modernen strukturierten objektorientierten Programmiersprachen? Ausnahmen sind genau dafür gedacht, STRUKTURIERT programmieren zu können, denn mit der modernen Exceptionbehandlung kann man endlich den normalen Ablauf kodieren, ohne nach jeder Zeile/Aufruf einen etwaigen Rückgabewert zu prüfen:
Strukturierte Programmierung à la grenzgaenger:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
ReturnCode := Step1;
If ReturnCode = RETURN_OK Then Begin
  ReturnCode := Step2;
  If ReturnCode = RETURN_OK Then Begin
    ReturnCode := Step3;
    If ReturnCode = RETURN_OK Then Begin
      ReturnCode := Step4;
      If ReturnCode = RETURN_OK Then Begin
        ReturnCode := Step5;
        ReportSuccess;
      End 
      Else 
        ShowError (ReturnCode)
     End 
     Else 
       ShowError (ReturnCode)
   End 
   Else 
     ShowError (ReturnCode)
  End 
  Else 
    ShowError (ReturnCode)
End 
Else 
 ShowError (ReturnCode);


Und so ist das laut grenzgaenger tödlich:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
Try
  Step1;
  Step2;
  Step3;
  Step4;
  Step5;
Except
  On E:Exception Do
    ShowError (E.ReturnCode)
End;

Die Frage, welches Fragment nun sicherer, wartbarer, verständlicher und robuster gegen Programmierfehler ist, erübrigt sich. Denke ich.

Abschließend würde ich deinem Lehrer erstmal folgen, denn es ist verständlich, das Breaks, Gotos und Exits am Anfang verboten sind. So lernt man erstmal, klare Programmstrukturen zu schreiben. Ihr schreibt ja schließlich nur kleine Programme, und da kann man ruhig eine Kontrolvariable (a.k.a. 'Found', 'Done' etc.) in einer Schleife mitschleppen. Bei einer einzelnen Schleife kann das durchaus Sinn ergeben, wenn nämlich dadurch der Sinn der Schleife ersichtlich wird: Eine Kontrollvariable namens 'Found' impliziert ja, das etwas gesucht wird.


Hidden - Sa 05.04.08 22:18

Hi,

Der Vorschlag von Grenzgänger ist - entschuldigung :D - banal. Ich hatte erst selbst überlegt, das als Beispiel zu nehmen, es dann aber doch gelassen. Wenn ihr meinen Post lest, ist das Problem aber ein etwas anderes. Ist es aber denn(in eurem Fall) nicht schneller, eine for-Schleife zu breaken, da bei dieser dem Compiler ja klar ist, dass du z.B. ein Array durchlaufen willst? Da müsste doch ein Maximum an Optimierung drin sein. Es ist ja nicht umsonst, dass die Variable komplett Prozessorintern läuft?

user profile iconLuckie hat folgendes geschrieben:
user profile iconHidden hat folgendes geschrieben:
c) try und bei Except ignorieren.

Wozu dann einen try-except-Block, wenn du die Exception doch ignorierst? So soll man ja Exceptions auch nicht verwenden. :roll:

Bei try end; meckert er leider. wäre try finally besser? mein ziel ist, dass bei einer Zugriffsverletzung durch ungültige Indizes einfach nichts passiert(außerhalb des Bretts braucht nicht geprüft werden, ob da ein Springer steht und Schach gibt...).

(wenn der except-Teil ausgelöst wird, läuft das programm doch ohne fehlermeldung weiter, oder :? )

Edit: Mein Lehrer hat sogar gesagt, dass allgemein die Verwendung von Befehlen, die auf ein GoTo herauslaufen gleichkommt mit dem Mathe-Ansatz in meiner Signatur :wink:

ich bin ja über unterstützung froh, aber ganz so schlimm wäre es nach grenzgaenger doch nicht:

Delphi-Quelltext
1:
2:
3:
4:
if not(Step1 or Step2 or Step3 or Step4 or Step5) then
  ShowError (ReturnCode)

else ReportSuccess;

Die hier nötige Kommentierung würde aber den Quelltext unnötig lang machen... Nachteil wäre natürlich, dass die Rückgabewerte Boolisch sein müssten und demnach undeferenziert. Außerdem müsste man den Code in Unterprozeduren, bzw. unterfunktionen, aufteilen. IMHO sehr unsauber.

Edit2: Mein Lehrer meinte übrigens, dass das nicht seine Meinung wäre sondern die aller Info-Lehrer. Und, dass Breaks etc. ausschließlich von Schülern benutzt würden. Ich werde ihm wohl die Möglichkeit geben, sich in diesem Tread dazu zu äußern, wenn er will.

mfG,


Yogu - Sa 05.04.08 22:49

user profile iconHidden hat folgendes geschrieben:
Bei try end; meckert er leider. wäre try finally besser? mein ziel ist, dass bei einer Zugriffsverletzung durch ungültige Indizes einfach nichts passiert

Bei try ... finally wird der Finally-Teil immer ausgeführt, egal, ob eine Exception aufgetreten ist oder nicht. Das ist wohl nicht dein Ziel :)

Du brauchst wenn dann schon try ... except. Das ist aber noch nicht ganz sauber. Du solltest diese Art von "Fehlerbehandlung" (;)) nur dann einsetzen, wenn es nicht anders geht. Und wenn, dann schon so:


Delphi-Quelltext
1:
2:
3:
4:
5:
try
  {Code, bei dem EMyException auftreten kann}
except
  on E: EMyException do Exit else raise;
end;

Du darfst die Exception wirklich nur verwerfen, wenn keine wirklich Ausnahme, sonder ein erwarteter Fehler aufgetreten ist. Alle anderen Fehler müssen weitergeleitet werden.

user profile iconHidden hat folgendes geschrieben:
Mein Lehrer meinte übrigens, dass das nicht seine Meinung wäre sondern die aller Info-Lehrer. Und, dass Breaks etc. ausschließlich von Schülern benutzt würden.

Da bin ich ja mal gespannt, ob ich Breaks vermeiden werde, wenn ich fortgeschrittener bin ;)


Hidden - Sa 05.04.08 23:06

Hi,


Delphi-Quelltext
1:
2:
3:
4:
5:
try
  {Code, bei dem EMyException auftreten kann}
except
  on E: EMyException do Exit else raise;
end;


und, wenn ich die EAcessViolation komplett gnorieren möchte, also auch kein Exit(sry für off Topic, nur weils auch in diesem vorgeschlagen wurde)?

Delphi-Quelltext
1:
2:
3:
4:
5:
try
  {Code, bei dem EMyException auftreten kann}
except
  on not (E: EMyException) do raise;  //oder wie?
end;


mfG,


alzaimar - So 06.04.08 10:04

user profile iconHidden hat folgendes geschrieben:
ich bin ja über unterstützung froh, aber ganz so schlimm wäre es nach grenzgaenger doch nicht:

Delphi-Quelltext
1:
2:
3:
if not(Step1 or Step2 or Step3 or Step4 or Step5) then
  ShowError (ReturnCode)
else ReportSuccess;


Nee, nee das geht nicht, die Aufrufreihenfolge ist nicht gewährleistet. Was wird denn zuerst ausgeführt? 'Step1' (Auswertung von links nach rechts, oder Step5 (Auswertung von rechts nach links)? Wie optimiert das der Compiler?
Und falls Du sicherstellen kannst, das die Reihenfolge stimmt (frage mich nur, wie), ist die Abfolge vom Compilerschalter 'vollständige boolsche Auswertung' abhängig. Ist er eingeschaltet, werden nämlich alle Programmschritte ausgeführt, selbst wenn 'Step1' fehlschlägt.

Zu Deiner Exception-Frage;

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
Try
  Try
    Foobar;
  Except
    On E:EMyException Do// Nur EMyException ignorieren
    On E:Exception Do Raise;
  End
Except
 On E:Exception Do Begin
  ... // Ab hier werden Alle Exception außer EMyException behandelt.
 End
End;

Und grundsätzlich: Die Exceptionbehandlung ist so dermaßen unperformant, das es eine ganz schlechte Idee ist, damit z.B. Arraygrenzen prüfen zu lassen. Insofern ist die Ignorieren einer Exception eigentlich immer ein Anzeichen für einen falschen Ansatz.

Was in diesem Thread zum Thema Exceptions steht, ist schon bedenklich: Exceptions haben nichts mit Pickeln oder Krätze zu tun, es sind Ausnahmen zum normalen Verhalten eines Programmflusses, nicht mehr nund nicht weniger. Es ist auch kein Weltuntergang, Exceptions zu behandeln oder selbst zu generieren, sondern zeugt von fundierter Kenntnis strukturierter Programmierung. Mit Exceptions werden Programme sogar sicherer und robuster. Beispiel:
// Mit Rückgabewerten, die wir aber ignorieren:

Delphi-Quelltext
1:
2:
RemoteConnection.Connect;
RemoteConnection.SendData; // Hier knallt es, wenn der Verbindungsaufbau nicht geklappt hat.

Wenn die Verbindung nicht geklappt hat, fahren wir das System unkontrolliert gegen die Wand. Und zwar nur deshalb, weil der Programmierer zu faul war, den Returncode auszuwerten. Oder er dachte sich: 'Klappt doch eh immer'. Wie viele Win-API-Aufrufe sind wohl so schlampig implementiert (ohne Abfrage des Returncodes), weil es schnell gehen muss?

Delphi-Quelltext
1:
2:
  RemoteConnection.Connect;
  RemoteConnection.SendData; // Wird nicht aufgerufen da das 'Connect' eine Exception wirft.

Ich kann also als schlampiger Programmierer mit Exceptions viel weniger Mist bauen.


zuma - So 06.04.08 10:20

user profile iconHidden hat folgendes geschrieben:
Mein Lehrer meinte übrigens, dass das nicht seine Meinung wäre sondern die aller Info-Lehrer. Und, dass Breaks etc. ausschließlich von Schülern benutzt würden.


Oh, dann bin ich ja nach 20Jahren in der Programmierung immer noch Schüler :shock: :lol:

ich nutz Break zwar auch eher selten, aber bei suche nach Performance sind die manchmal die einzige Chance,
Exit nutz ich auch gerne am beginn, wenn ich erstmal Parameter checke o.ä. Sehe da auch keine Probleme, allerdings sollte man versuchen, jede Procedure/Function wie ein eigenes Programm zu betrachten. Wenn der Aufbau der Methoden sauber ist, sind alle Befehle gültig/erlaubt/Sauber:
ein exit vor dem init von Var's ist z.b. imho unsauber, danach aber nicht unbedingt.
meine methoden machen immer* erstmal 'ihren eigenen Init',
dann werden evtl. übergebene parameter geprüft,
dann kommt erst die eigentliche Logik.

*(immer heisst natürlich: immer, wenn ich die Zeit dafür bezahlt bekomme :mrgreen:)


Hidden - So 06.04.08 11:34

Hi,

Ich bin mir nicht ganz sicher, was du mit "ihren eigenen init" meinst. a) resultwert festlegen(klar) b) alle Hilfsobjekte, die während der Prozedur erzeugt werden, erzeugen: Kann ich mir nicht vorstellen, das macht doch nur unnötige Arbeit, wenn sie beim exit nicht verwendet werden und dann noch vor dem exit freigegeben werden müssen?

Mein Ansatz beim ignorieren der EAccessViolation war, eine einzelne Validitätsprüfung für jedes zu prüfende Feld zu vermeiden. Ist das falsch?

mfG,


BenBE - So 06.04.08 12:51

Sorry, aber was hier einige erzählen, konnte ja nicht mal Münchhausen so gut darstellen!

Zu den Exceptions:

Diese sollten vermieden werden, da deren Behandlung zeitaufwendig ist. Außerdem erzeugt die Behandlung von Exceptions overhead im Kernel-Mode, da das System einen Kontext-Snapshot anfertigen muss. Wenn man also allein mit Exceptions "kontrolliert" sein Programm runterfährt, mag man zwar "einen Sicheren" Zustand haben, provoziert aber u.U. genau das Gegenteil.

Nehmen wir an:


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
var X: Integer;

function Foo1: Boolean;
begin
    try
        Result := Foo2;
    except
        Raise Exception.Create('Foo1');
    end;
end;

function Foo2: Boolean;
begin
    try
        Result := Foo3;
    except
        Raise Exception.Create('Foo2');
    end;
end;

function Foo3: Boolean;
begin
    try
        Result := 42 div x = 42;
    except
        Raise Exception.Create('Foo3');
    end;
end;


Dann frisst die Behandlung nicht nur im Fehlerfalle den Speicher für 3 Exception, Objekte, sondern führt MINDESTENS 2 Kontext-Wechsel aus, bei denen das "Notstandssystem" des Betriebssystem eine Kontext-Sicherung ausführt. Außerdem kommt hinzu, dass jeder dieser Except-Blöcke 2fach angesprungen wird (1. für's Handling, 2. für's Unwinding) und man damit so viel Speicher und Rechenzeit verbrät, dass man den Fehler x=0 hätte 100 mal Abfragen können. Wenn jetzt jemand kommt, Nested Exceptions fängt man ab und reicht sie mit Raise weiter: Ja, ist aber nichts andres, als das Beispiel.

Und ein weiterer Nachteil, den SEH hat, ist die Tatsache, dass selbst, wenn kein Fehler auftritt Zeit verschwendet wird, die man für sinnvolleres verwenden kann ... z.B. um die Fehler-Rahmenbedingungen zu prüfen ...

Wer also ernsthaft der Meinung ist, sein Programm mit SEH vollzupflastern, mag zwar in Software-Technik "Exceptions sind gut" verstanden haben, hat aber im Gegenzug keinen Plan, wie dieses Mittel arbeitet und sollte bitte nicht nur an der Oberfläche kratzen.

P.S.: Die Verwendung globaler Variablen in diesem Beispiel ist Absicht :P


hansa - So 06.04.08 13:08

Man kann für jeden Fall einen anderen Fall konstruieren, um irgendwelche Vorteile einer Methode zu verdeutlichen. Ungefähr so, wie Alzaimar das gemacht hat. :mrgreen: Ich überlege gerade, ob bei einem Schachspiel nicht tatsächlich ein Exit gut wäre, denn das sind ja immer genau 8x8 Felder, die behandelt werden müssen. Allgemein gilt allerdings folgendes : wer goto benutzt, der wird gesteinigt. Wer Exit benutzt, der kriegt auf die Finger gekloppt ! Bei Break wird ganz besonders gut nachgeguckt. Prinzipiell heißt es also schon : Finger weg von dem Kram. Das wird tatsächlich jeder Lehrer/Prof. sagen. Dass es Ausnahmen von der Regel gibt, das habe ich hier nicht gesagt ! :lol: Ne, das merkt man schon irgendwann selber. Anfangs hatte ich auch viele Exits benutzt. Ist ja so schön einfach. Bis dann eine tagelange Fehlersuche begann. Ergebnis : ALLE Exits rausschmeißen und neu testen. Fehler waren weg. Das war wie mit der Herdplatte und den kleinen Kindern. :mrgreen:


Hidden - So 06.04.08 13:17

Hi,

Es geht nicht darum, ein Schachbrett zu durchlaufen. Es soll bestimmt werden, ob ein König im Schach steht. Dazu prüfe ich zunächst die unmittelbare Umgebung auf Springer, Bauern und den 2.König(not Schach(Stellung) ist validationsbedingung für "Zug möglich", daher dies auch, obwohl defakto kein König an den anderen herankommt).

Nachdem ich auf diese Möglichkeiten geprüft habe, gehe ich in alle 8 Richtungen die Reihen vom König ab durch und prüfe auf Schachgeber(Dame, Turm, Läufer). Wenn dir etwas besseres dazu einfällt, kannst du es dir aufheben, da ich die Logik-Unit wahrscheinlich in der entsprechenden Open-Source-Sparte posten werde :D .

Edit: Danke, BenBe! ich werde den try-Block durch eine Validitätsprüfung ersetzen. oder ist es besser, das Schachbrett größer zu machen und mit nil zu füllen?

Die Exits lasse ich erstmal. Da dürft ihr dann beim o.e. Posting drauf rumhacken :mrgreen:

mfG,


alzaimar - So 06.04.08 13:45

user profile iconBenBE hat folgendes geschrieben:
Und ein weiterer Nachteil, den SEH hat, ist die Tatsache, dass selbst, wenn kein Fehler auftritt Zeit verschwendet wird, die man für sinnvolleres verwenden kann ... z.B. um die Fehler-Rahmenbedingungen zu prüfen ...

Du meinst also, ich soll prüfen, ob (wie in meinem Beispiel) eine Verbindung zustande kommen kann, anstatt eventuell eine Exception abzufangen? Was soll ich denn dann prüfen? Ich weiss doch gar nicht, was für eine Verbindung das ist? Und die Verbindung selbst macht das ja und meldet sich bei mir über Exceptions. So macht man das nun mal und so ist es auch richtg.

Im 'Kleinen', also bei einfachen Dingen wie z.B. der Prüfung der Arraygrenzen, kommt es auf Performance an und es ist auch sinnvoller, hier direkt zu prüfen, als den Karren blind gegen die Wand fahren zu lassen. Das ist nicht nur hirnrissig, sondern kostet auch gewaltig an Performance, wie Du schon erwähnt hast.
user profile iconBenBE hat folgendes geschrieben:

Wer also ernsthaft der Meinung ist, sein Programm mit SEH vollzupflastern, mag zwar in Software-Technik "Exceptions sind gut" verstanden
haben, hat aber im Gegenzug keinen Plan, wie dieses Mittel arbeitet und sollte bitte nicht nur an der Oberfläche kratzen.

Nun ist es so, das größere Systeme nun mal "à la Softwaretechnik" implementiert werden müssen, um eben überhaupt den Überblick zu erhalten. Da sind Performanceüberlegungen zweitrangig.

Letztendlich muss alles mit Bedacht und Fingerspitzengefühl verwendet werden, nach dem Motto: "So viel wie nötig, aber so wenig wie möglich". Das gilt für Exceptions genauso wie für obskure Programmsprünge, Objekte, eben Alles, was in so einem Programm drinsteckt.

Hier pauschal von 'Exit', 'Exceptions' oder so abzuraten ist genauso falsch, wie zu behaupten, das man die Finger vom Auto lassen soll, weil neulich mal einer umgefahren wurde.

user profile iconhansa hat folgendes geschrieben:
Man kann für jeden Fall einen anderen Fall konstruieren, um irgendwelche Vorteile einer Methode zu verdeutlichen. Ungefähr so, wie Alzaimar das gemacht hat. :mrgreen:

Zeig mal ein Beispiel, in dem die Verwendung von Rückgabeparametern übersichtlicher und in der Benutzung auch sicherer ist, als mit Exceptions. Das würde mich interessieren.

user profile iconhansa hat folgendes geschrieben:
Allgemein gilt allerdings folgendes : wer goto benutzt, der wird gesteinigt. Wer Exit benutzt, der kriegt auf die Finger gekloppt!
Das kann man unterschreiben, aber nur weil das 'Allgemein gilt allerdings...' davor steht. Denn im *Einzelfall* ist alles erlaubt.


hansa - So 06.04.08 13:58

user profile iconalzaimar hat folgendes geschrieben:
..Denn im *Einzelfall* ist alles erlaubt.


Goto aber nicht. :lol: Das gibts nur, weil den Basic/Cobol-Programmierern die letzte Ausrede für einen Wechsel zu Pascal genommen werden musste. Gerne wurde es allerdings nicht eingebaut. Goto passt zu Pascal, wie die Faust aufs Auge. :mrgreen:

P.S.: zu Exceptions habe ich nichts gesagt. Da halte ich mich raus. :D


BenBE - So 06.04.08 15:37

user profile iconalzaimar hat folgendes geschrieben:
user profile iconhansa hat folgendes geschrieben:
Man kann für jeden Fall einen anderen Fall konstruieren, um irgendwelche Vorteile einer Methode zu verdeutlichen. Ungefähr so, wie Alzaimar das gemacht hat. :mrgreen:

Zeig mal ein Beispiel, in dem die Verwendung von Rückgabeparametern übersichtlicher und in der Benutzung auch sicherer ist, als mit Exceptions. Das würde mich interessieren.


Z.B. die WinAPI (Ich weiß, nicht grad ein Meisterstück in saubrer Programmierung). Was mein ich da speziell: Wenn man von einer API-Funktion einen String haben will, muss man der WinAPI sagen, wo dieser hin soll und wieviel Platz sie dafür hat. Die WinAPI passt dann den übergebenen Puffer an, so dass in diesem der String enthalten ist und gibt als Return-Wert die !BENÖTIGTE! Menge an Speicher aus. Tritt ein Fehler auf, so wird ein definierter Wert zurückgegeben, auf den man Prüfen kann und hat dann die Möglichkeit, die genaue Ursache an andrer Stelle zu erfragen.

Ohne Rückgabe-Parameter würde man hier 20 Funktionen haben, die haufenweise Code-Doppelung hätten und bringen würde es im Endeffekt nicht viel. Nachteilig ist zwar bei dieser Art und Weise, dass man eine API 2-mal aufrufen muss; wenn man aber ausreichende Puffer von Vornherein übergibt, kann in den meisten Fällen der zweite Aufruf durchaus entfallen.


dummzeuch - So 06.04.08 16:45

user profile iconHidden hat folgendes geschrieben:

Edit2: Mein Lehrer meinte übrigens, dass das nicht seine Meinung wäre sondern die aller Info-Lehrer. Und, dass Breaks etc. ausschließlich von Schülern benutzt würden.

Was willst Du eigentlich erreichen? Deinen Lehrer vor der Klasse blossstellen? Das hilft weder Dir noch ihm noch der Klasse.

Er macht seinen Job und dazu gehoert es Euch die Grundlagen der Programmierung beizubringen. Hinterher seid Ihr keine ausgebildeten Programmierer und schon gar keine Experten sondern wisst nur ungefaehr, wie man es macht. Und sein Hinweis, dass man Goto, Exit und Break (in Pascal, denn in C muss man in Case-Statements Break verwenden) vermeiden sollte, ist im Prinzip korrekt. Wer sich darueber im Klaren ist, dass er etwas "verbotenes" tut, ueberlegt es sich mehrmals, ob es nicht einen anderen - besseren Weg gibt.

Wenn der Sinn des Unterrichts waere, Euch zu Programmierern zu machen, die sofort bei der naechsten Softwareklitsche anfangen koennen, dann wuerde auch nicht Delphi gelehrt sondern Java oder C#. Damit will ich definitiv nicht behaupten, dass man mit Delphi keine "richtigen" Programme schreiben kann, schliesslich verdiene ich damit seit Jahren mein Geld. Allerdings sind die Jobs als Delphi-Entwickler relativ duenn gesaeht. Als Anfaengersprache ist Delphi (bzw. das ihm zugrunde liegende Pascal) sehr gut geeignet. Wer die Grundlagen verstanden hat, sollte keine Problem haben, sie auf andere Programmiersprachen zu uebertragen. Wer das nicht schafft, sollte von einer Karriere als Programmierer Abstand nehmen.

Nochmal konkret zu der Aussage Deines Lehrers:

Wenn er das obige wirklich so behauptet hat, so liegt er falsch. Ich bin schon laenger kein Schueler und auch kein Student mehr sondern arbeite seit ueber 10 Jahren als Softwareentwickler. Ich halte mich zwar nicht fuer der Welt besten Programmierer, aber wuerde mich durchaus zum oberen Drittel zaehlen ;-)

Ich habe in dieser Zeit mehrfach Gotos verwendet, allerdings in nur wenigen Ausnahmefaellen, denn in den meisten Faellen machen sie den Quellcode schlechter verstaendlich und sind in Pascal auch umstaendlich zu benutzen, weil man ja die Labels vorher deklarieren muss (und das ist gut so!).

Break und Exit benutze ich haeufiger, naemlich immer dann, wenn sie die Verstaendlichkeit des Sourcecodes verbessern. Ich empfehle uebrigens ein Tool wie Castalia einzusetzen, welches Exits und Breaks im Code hervorhebt, so dass man sie nicht so leicht uebersieht. Ausserdem sollte man sie aus demselben Grund alleine in eine Zeile schreiben.

Es ist aber definitiv kein Fehler, wenn man weiss, wie man diese Konstrukte vermeidet, denn evtl. spaetere Programmaenderungen koennen dazu fuehren, dass man sie durch eine fuer den neuen Zweck besser geeignete Konstruktion ersetzen muss. Das muss uebrigens nicht immer ein weiterer Begin-End Block sein, haeufig ist ein Prozedur- oder Funktionsaufruf sinnvoller, denn im gegensatz zu einem einfachen Begin-End hat dieser einen Namen, den man natuerlich so waehlen sollte, dass man auch zwei Jahre spaeter noch versteht, was sie macht.

Zum Thema Performance von for vs. while: Computerleistung ist billig und wird seit Jahren billiger. Programmiererzeit ist teuer. Schlecht verstaendlicher Sourcecode kostet Programmiererzeit, wenig optimierter Code kostet Computerzeit. Wenn man das beruecksichtigt, wie wichtig ist es dann, ob eine For-Schleife gegenueber einer While-Schleife evtl. 10 Prozessorzyklen einspart?
Nur in wenigen Faellen lohnt es sich, ueber Optimierungen ueberhaupt nachzudenken, naemlich dann, wenn man feststellt, dass das Programm zu langsam ist. Und dann sollte man ueberpruefen, wo denn der Flaschenhals wirklich ist, denn meist sind das Festplattenzugriffe und nicht ineffizienter Code.

twm


alzaimar - So 06.04.08 17:36

user profile iconhansa hat folgendes geschrieben:
user profile iconalzaimar hat folgendes geschrieben:
..Denn im *Einzelfall* ist alles erlaubt.

Goto aber nicht. :lol:

Doch, wenn es klar verständlich ist.

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
While SomeCondition Do
  While AnotherCondition Do
    While FinalCondition Do
      If StopAllLoops Then Goto EndLoops;

EndLoops: ...

Man sieht sofort das Sprungziel und erkennt, das man sich sonst einen abbrechen müsste. Das ist übersichtlich und sauber, aber natürlich durch eine lokale Prozedur mit Exit zu ersetzen...

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
Procedure...
  Procedure _DoTheLoop;
  Begin
    While SomeCondition Do
      While AnotherCondition Do
        While FinalCondition Do
          If StopAllLoops Then Exit;
  End;

Begin
  _DoTheLoop;
...

Ich pflichte Dir aber bei, das man das Goto auch abschaffen könnte.

@BenBE: Wollt' grad noch sagen: Aber nicht die Win-API :wink: ... Dein Beispiel hat aber nix mit Exceptions zu tun, sondern mit Kommunikation. Das ist in Ordnung (für die Win-API), obwohl es wirklich ziemlich umständlich ist. Ein etwas anderes Alloziierungskonzept wäre hier einfacher und robuster. Aber das ist Ansichtssache.
Ich behaupte immer noch, das Exceptions ab zwei aufbauenden Aufrufen IMMER übersichtlicher sind, als Rückgabewerte.


Hidden - So 06.04.08 17:37

user profile icondummzeuch hat folgendes geschrieben:
user profile iconHidden hat folgendes geschrieben:

Edit2: Mein Lehrer meinte übrigens, dass das nicht seine Meinung wäre sondern die aller Info-Lehrer. Und, dass Breaks etc. ausschließlich von Schülern benutzt würden.

Was willst Du eigentlich erreichen? Deinen Lehrer vor der Klasse blossstellen? Das hilft weder Dir noch ihm noch der Klasse.

Er macht seinen Job und dazu gehoert es Euch die Grundlagen der Programmierung beizubringen. Hinterher seid Ihr keine ausgebildeten Programmierer und schon gar keine Experten sondern wisst nur ungefaehr, wie man es macht. Und sein Hinweis, dass man Goto, Exit und Break (in Pascal, denn in C muss man in Case-Statements Break verwenden) vermeiden sollte, ist im Prinzip korrekt. Wer sich darueber im Klaren ist, dass er etwas "verbotenes" tut, ueberlegt es sich mehrmals, ob es nicht einen anderen - besseren Weg gibt.


Hi,

Ersteinmal danke für deinen langen Beitrag :) . Meinen Lehrer bloßstellen will ich ganz bestimmt nicht. Dass breaks, etc., im Unterricht, zumindest von mir, nichtmehr verwendet werden, steht für mich außer Frage. Nur interessierte mich natürlich, wo denn da ein Sicherheitsfehler liegen könnte, da auch ich der Meinung war, dass diese vom Compiler sowieso verwendet werden...

mfG,


Yogu - So 06.04.08 17:57

user profile iconalzaimar hat folgendes geschrieben:
[...] aber natürlich durch eine lokale Prozedur mit Exit zu ersetzen...

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
Procedure...
  Procedure _DoTheLoop;
  Begin
    While SomeCondition Do
      While AnotherCondition Do
        While FinalCondition Do
          If StopAllLoops Then Exit;
  End;

Begin
  _DoTheLoop;
...

Warum nicht mit Break? Exit dürfte doch wohl kaum besser sein als Break.


Delphi-Quelltext
1:
2:
3:
4:
while SomeCondition do
  while AnotherCondition do
    while FinalCondition do
      if StopAllLoops then Break;


Hidden - So 06.04.08 18:05

user profile iconYogu hat folgendes geschrieben:
user profile iconalzaimar hat folgendes geschrieben:
[...] aber natürlich durch eine lokale Prozedur mit Exit zu ersetzen...

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
Procedure...
  Procedure _DoTheLoop;
  Begin
    While SomeCondition Do
      While AnotherCondition Do
        While FinalCondition Do
          If StopAllLoops Then Exit;
  End;

Begin
  _DoTheLoop;
...

Warum nicht mit Break? Exit dürfte doch wohl kaum besser sein als Break.


Delphi-Quelltext
1:
2:
3:
4:
while SomeCondition do
  while AnotherCondition do
    while FinalCondition do
      if StopAllLoops then Break;


Hi,

Nach meinem Verständnis wird hier nur die letzte Schleife gebreakt...

mfG,


alzaimar - So 06.04.08 18:24

Preisfrage:
Beim Goto kann ich die Diskussion noch nachvollziehen, beim Break... nun ja, ich finds praktisch, aber das man nun auch das exit verteufelt, also das geht zu weit. Wo iss'n der Unterschied zwischen einem Exit und einem (C#, C, C++, Java) Return? Normalerweise argumentiere ich ja nicht so ("Leute! Fresst sche****! 1 Mio Fliegen können nicht irren"), aber wenn alle modernen Programmiersprachen das 'Break', 'Continue' und 'Exit/Return' unterstützen, wieso soll das dann so schrecklich sein?

Der Lehrer mit dem Sicherheitsrisiko ist ein typischer Vertreter der Lehrkräfte, die den Schülern IT 'beibringen'. Daran hat sich seit 30 Jahren nichts geändert (damals hatte ich das Vergnügen, einem Informatiklehrer erklären zu müssen, wie man richtig kodiert).


dummzeuch - So 06.04.08 18:48

user profile iconalzaimar hat folgendes geschrieben:

Wo iss'n der Unterschied zwischen einem Exit und einem (C#, C, C++, Java) Return? Normalerweise argumentiere ich ja nicht so ("Leute! Fresst sche****! 1 Mio Fliegen können nicht irren"), aber wenn alle modernen Programmiersprachen das 'Break', 'Continue' und 'Exit/Return' unterstützen, wieso soll das dann so schrecklich sein?


Es gibt einen Unterschied zwischen "ist moeglich" und "ist eine gute Idee". Die Aufgabe eines Lehrers ist es, den Schuelern beizubringen, was man machen sollte und was man vermeiden sollte (und moeglichst auch, warum). Mit Exit kann man definitv auch viel Bloedsinn anstellen. Es deswegen komplett zu verteufeln halte ich allerdings auch fuer uebertrieben.

Zitat:

Der Lehrer mit dem Sicherheitsrisiko ist ein typischer Vertreter der Lehrkräfte, die den Schülern IT 'beibringen'. Daran hat sich seit 30 Jahren nichts geändert (damals hatte ich das Vergnügen, einem Informatiklehrer erklären zu müssen, wie man richtig kodiert).


Was, vor 30 Jahren (1978) hattest Du schon Informatikunterricht? In "meiner" Schule wurde der erst eingefuehrt, nachdem ich Abi gemacht hatte (1985). Naja, war vielleicht auch gut so. Vielleicht haette mir sonst ein schlechter Lehrer den Spass daran verdorben und ich haette was anstaendiges gelernt...

twm


alzaimar - So 06.04.08 18:52

user profile icondummzeuch hat folgendes geschrieben:
Es gibt einen Unterschied zwischen "ist moeglich" und "ist eine gute Idee". Die Aufgabe eines Lehrers ist es, den Schuelern beizubringen, was man machen sollte und was man vermeiden sollte (und moeglichst auch, warum). Mit Exit kann man definitv auch viel Bloedsinn anstellen. Es deswegen komplett zu verteufeln halte ich allerdings auch fuer uebertrieben.

Das lassen wir mal als Zusammenfassung so stehen.


Hidden - Mo 07.04.08 20:41

user profile iconHidden hat folgendes geschrieben:
user profile iconYogu hat folgendes geschrieben:
user profile iconalzaimar hat folgendes geschrieben:
[...] aber natürlich durch eine lokale Prozedur mit Exit zu ersetzen...

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
Procedure...
  Procedure _DoTheLoop;
  Begin
    While SomeCondition Do
      While AnotherCondition Do
        While FinalCondition Do
          If StopAllLoops Then Exit;
  End;

Begin
  _DoTheLoop;
...

Warum nicht mit Break? Exit dürfte doch wohl kaum besser sein als Break.


Delphi-Quelltext
1:
2:
3:
4:
while SomeCondition do
  while AnotherCondition do
    while FinalCondition do
      if StopAllLoops then Break;


Hi,

Nach meinem Verständnis wird hier nur die letzte Schleife gebreakt...

mfG,


Tschuldigung für den langen quote :?
Aber der Tread scheint ja fürs erste tot und ich bräuchte hier noch eine Antwort: Break breakt doch nur die letzte Schleife und nicht alle, oder?

mfG,


BenBE - Mo 07.04.08 20:43

Break breakt nur die letzte (innerste) Schleife.


Yogu - Mo 07.04.08 20:53

user profile iconHidden hat folgendes geschrieben:
[quoBreak breakt doch nur die letzte Schleife und nicht alle, oder?

Ja. War mein Denkfehler, sorry. :oops:


Strike Eagle - Do 10.04.08 17:35

user profile iconhansa hat folgendes geschrieben:
user profile iconalzaimar hat folgendes geschrieben:
..Denn im *Einzelfall* ist alles erlaubt.


Goto aber nicht. :lol:
Wenn ich dir einen Teil eines Codes von mir vorsetzen würde, würdest du das revidieren. Zwei Gotos waren das einzige, das ohne größeren Aufwand und noch viel mehr Unübersichtlichkeit praktikabel funktionierte (Sprache: C#)!

Wobei ich nicht verstehe, wieso ihr da so einen großen Terz drum macht, ist ja fast schon episch hier. :D Im PC intern geht es doch sowieso nur so. Und wenn ich manchen Code so sehe, wie gekünstelt es sit mit einer while-Schleife zu arbeiten und zum vorzeitigen Abbruch den Zähler hochzustellen, ne da bekommt man das kalte Grausen. Der Code ging von 170 auf knapp über 100 Zeilen runter, nachdem ich damit fertig war. Übersicht? Jawohl!

Es gibt auch noch Break label, das springt dann aus mehreren raus. (OK, war glaube ich nur in Java so, ist halt der Ersatz fürn goto)