Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Sinnvoller Einsatz von goto (https://www.delphipraxis.net/149370-sinnvoller-einsatz-von-goto.html)

Luckie 19. Mär 2010 23:36


Sinnvoller Einsatz von goto
 
Der Einsatz von goto wird ja immer so verteufelt. Ich habe das bisher eigentlich schon immer etwas differenziert gesehen, hatte bisher nur nie die Situation, in der ein goto sinnvoll gewesen wäre. Aber ich denke, gerade eben bin ich über einen sinnvollen Einsatz gestolpert:

Delphi-Quellcode:
function DemoThread(p: Pointer): Integer;
var
  i: Integer;
  ParentHandle: THandle;
  label CLEANUP;
begin
  ParentHandle := PThreadParams(p)^.ParentHandle;
  for i := 0 to 9 do
  begin
    if Abort then
    begin
      SendMessage(ParentHandle, CM_ABORT, 0 , 0);
      goto CLEANUP;
    end;
    SendMessage(ParentHandle, CM_STATUS, Integer(PChar('Durchlauf:')), i);
    Sleep(500);
  end;
  SendMessage(ParentHandle, CM_FINISHED, 0, 0);
CLEANUP:
  Dispose(p);
  Result := 0;
end;
Ich stelle das hier einfach mal zur Diskussion.

Christian Seehase 20. Mär 2010 00:00

Re: Sinnvoller Einsatz von goto
 
Moin Michael,

ja, da könnte man wohl goto verwenden, aber mir gefällt folgende Lösung besser:

Delphi-Quellcode:
function DemoThread(const AParentHandle : THandle): Integer;
var
  i: Integer;

begin
  for i := 0 to 9 do
  begin
    if Abort then
    begin
      SendMessage(AParentHandle, CM_ABORT, 0 , 0);
      break;
    end else begin
      SendMessage(AParentHandle, CM_STATUS, Integer(PChar('Durchlauf:')), i);
      Sleep(500);
    end;
  end;
  if not Abort then SendMessage(AParentHandle, CM_FINISHED, 0, 0);
  Result := 0;
end;
BTW:
Den Speicher in der Funktion freizugeben, halte ich nicht für sinnvoll, da er ja dort nicht belegt wird.

Luckie 20. Mär 2010 00:06

Re: Sinnvoller Einsatz von goto
 
Das wäre natürlich eine Lösung. Allerdings finde ich meine besser lesbar.

Wollte ich den Speicher nicht in der Thread-Funktion frei geben, müsste ich die Variable global machen und doch wieder an anderer Stelle im Code freigeben. So hat man den direkten Bezug, auch wenn es natürlich oftmals schöner ist den Speicher dort wieder frei zu geben, wo man ihn anfordert. Da stimme ich dir zu.

Neutral General 20. Mär 2010 00:37

Re: Sinnvoller Einsatz von goto
 
Nunja ein try-finally wäre wohl die richtige Wahl in dieser Situation ;)

Delphi-Quellcode:
function DemoThread(p: Pointer): Integer;
var
  i: Integer;
  ParentHandle: THandle;
begin
  try
    ParentHandle := PThreadParams(p)^.ParentHandle;
    for i := 0 to 9 do
    begin
      if Abort then
      begin
        SendMessage(ParentHandle, CM_ABORT, 0 , 0);
        exit;
      end;
      SendMessage(ParentHandle, CM_STATUS, Integer(PChar('Durchlauf:')), i);
      Sleep(500);
    end;
    SendMessage(ParentHandle, CM_FINISHED, 0, 0);
  finally
    Dispose(p);
    Result := 0;
  end;
end;

Luckie 20. Mär 2010 00:47

Re: Sinnvoller Einsatz von goto
 
Stellt sich die Frage, ob nach dem Exit der finally-Abschnitt noch abgearbeitet wird. Wenn dem so ist, dann spricht natürlich nichts gegen deine Lösung.

Neutral General 20. Mär 2010 00:53

Re: Sinnvoller Einsatz von goto
 
Der wird noch abgearbeitet. Ist mir auch erst vor kurzem eher rein zufällig beim Debuggen aufgefallen ;)

Luckie 20. Mär 2010 00:55

Re: Sinnvoller Einsatz von goto
 
Das try-finally gefällt mir sogar besser, weil da sicher gestellt wird, dass der Speicher wieder freigegeben wird.

Sir Rufo 20. Mär 2010 01:05

Re: Sinnvoller Einsatz von goto
 
Zitat:

Zitat von Neutral General
Der wird noch abgearbeitet. Ist mir auch erst vor kurzem eher rein zufällig beim Debuggen aufgefallen ;)

Hätte mich aber auch gewundert, wenn nicht.

War try...finally nicht so definiert, dass der finally-Teil in jedem Fall abgearbeitet wird,
egal was zwischen try und finally passiert?

Gut es gibt da schon Ausnahmen, die aber von dieser Betrachtung ausgeschlossen werden können:

- Stromausfall
- internationaler Weltuntergang
- etc.

um nur einige zu nennen :mrgreen:

Medium 20. Mär 2010 02:18

Re: Sinnvoller Einsatz von goto
 
Zitat:

Zitat von Sir Rufo
- internationaler Weltuntergang

Nationale wären nicht so schlimm? :stupid:

alzaimar 20. Mär 2010 06:39

Re: Sinnvoller Einsatz von goto
 
Da die Funktion zwei Aufgaben erfüllt (sende Nachrichten und räume auf), teilen wir sie. Da ein Goto zu 99.9% der Fälle eine Aufgabe beendet, fällt das Goto nun automatisch weg. Das ist kein Trick, sondern sowieso Pflicht, um das SRP (Single Responsibility Princip) auf funktionaler Ebene einzuhalten.
Delphi-Quellcode:
procedure TryHardToSendMessages (aParentHandle : THandle);
var
  i: Integer;

begin
  for i := 0 to 9 do begin
    if Abort then begin
      SendMessage(ParentHandle, CM_ABORT, 0 , 0);
      exit;
    end;
    SendMessage(ParentHandle, CM_STATUS, Integer(PChar('Durchlauf:')), i);
    Sleep(500);
  end;
  SendMessage(ParentHandle, CM_FINISHED, 0, 0);
End;

function DemoThread(p: Pointer): Integer;
begin
  Try
    TryHardToSendMessages (PThreadParams(p)^.ParentHandle);
  Finally
    Dispose(p);
  End;
  Result := 0;
end;
Hmm. Das mit der Schleife und dem Abort-Flag geht ja nun mal gar nicht (Abort ist ein reserviertes Schlüsselwort):
Außerdem und überhaupt ist nicht so richtig klar, wie die Nachrichten verwendet werden sollen. Mal sehen:

Wir senden 10x eine Nachricht 'CM_STATUS'. Nach jeder Nachricht warten wir 500ms.
Wenn alle 10 Nachrichten verschickt haben, senden wir ein 'CM_FINISHED'.
Wurden wir ausnahmsweise (<-Zaunpfahl) unterbrochen, senden wir ein CM_ABORT.
Delphi-Quellcode:
Procedure TryHardToSendMessages (aParentHandle : THandle);
var
  i: Integer;

begin
  Try
    for i := 0 to 9 do
      if ExternalAbort then
        abort
      else begin
        SendMessage(ParentHandle, CM_STATUS, Integer(PChar('Durchlauf:')), i);
        Sleep(500);
      end
 
    SendMessage(ParentHandle, CM_FINISHED, 0, 0);
  Except
// TODO: Vollständige Exceptionbehandlung
    SendMessage(ParentHandle, CM_ABORT, 0 , 0);
   end;
end;
Hier eine Alternative ohne Exceptions, sondern mit einer Funktion, die den Erfolg als Rückgabewert liefert.
Delphi-Quellcode:
Function Sending10MessagesWasNotAborted(aParentHandle) : Boolean;
Var
  i : Integer;

Begin
  for i := 0 to 9 do
    if ExternalAbort then
      break
    else begin
      SendMessage(ParentHandle, CM_STATUS, Integer(PChar('Durchlauf:')), i);
      Sleep(500);
    end;
  Result := ExternalAbort;
End;
 
Procedure TryHardToSendMessages (aParentHandle : THandle);
begin
  If Sending10MessagesWasNotAborted(aParentHandle) Then
    SendMessage(ParentHandle, CM_FINISHED, 0, 0)
  else
    SendMessage(ParentHandle, CM_ABORT, 0 , 0);
end;
Das ist -finde ich- noch lesbarer.
Nachteil der 2.Variante bzw. des dort verwendeten Verfahrens: Wenn dieses Paradigma durchgezogen wird, entstehen schnell verschachtelte und unleserliche If-Then-Abläufe, z.B.:
Delphi-Quellcode:
..
  If Action1IsSuccessfull then
    If Action2IsSuccessfull then
      If Action3IsSuccessfull then
        DoSomething
      else
        HandleException
    else
      HandleException
  else
    HandleException
..
Dann lieber so (Try-Except-Paradigma)
Delphi-Quellcode:
...
Try
  Action1;
  Action2;
  Action3;
Except
  HandleException;
End;
Paradigmen sollten zwar stringent durchgezogen werden, aber wozu sind solche Regeln da, wenn nicht zum brechen? :mrgreen:

samso 20. Mär 2010 07:24

Re: Sinnvoller Einsatz von goto
 
N.B. Und vielleicht auch noch die 64-Bit-Version vorbereiten:

Delphi-Quellcode:
{$IF (CompilerVersion<20.00)}
Type
  NativeInt = type Integer;    //Delphi2007: SizeOf(NativeInt)<>4(!)
{$IFEND}
...
SendMessage(ParentHandle, CM_STATUS, NativeInt(PChar('Durchlauf:')), i);
...
Mist - zereditiert

jfheins 20. Mär 2010 07:29

Re: Sinnvoller Einsatz von goto
 
Zitat:

Zitat von samso
N.B. Und vielleicht auch noch die 64-Bit-Version vorbereiten:

:?: :?: :?:
Integer bleibt 32 bittig, wenn ich richtig informiert bin ....

alzaimar 20. Mär 2010 07:31

Re: Sinnvoller Einsatz von goto
 
Das hat dann aber nicht mehr soooo viel mit GOTO zu tun, dem Thema des Threads.

samso 20. Mär 2010 07:45

Re: Sinnvoller Einsatz von goto
 
Zitat:

Integer bleibt 32 bittig, wenn ich richtig informiert bin ....
Darum ja, denn PChar wird 64-Bit.

alzaimar 20. Mär 2010 08:34

Re: Sinnvoller Einsatz von goto
 
Zitat:

Zitat von samso
Zitat:

Integer bleibt 32 bittig, wenn ich richtig informiert bin ....
Darum ja, denn PChar wird 64-Bit.

Zitat:

Zitat von alzaimar
Das hat dann aber nicht mehr soooo viel mit GOTO zu tun, dem Thema des Threads.

*Tap* *Tap* *Tap*

himitsu 21. Mär 2010 22:45

Re: Sinnvoller Einsatz von goto
 
Delphi-Quellcode:
function DemoThread(p: Pointer): Integer;
var
  i: Integer;
  ParentHandle: THandle;
begin
  ParentHandle := PThreadParams(p)^.ParentHandle;
  for i := 0 to 9 do
  begin
    if Abort then
    begin
      SendMessage(ParentHandle, CM_ABORT, 0 , 0);
      Break;
    end;
    SendMessage(ParentHandle, CM_STATUS, Integer(PChar('Durchlauf:')), i);
    Sleep(500);
    if i = 9 then SendMessage(ParentHandle, CM_FINISHED, 0, 0);
  end;
  Dispose(p);
  Result := 0;
end;

Delphi-Quellcode:
function DemoThread(p: Pointer): Integer;
var
  i: Integer;
  ParentHandle: THandle;
begin
  ParentHandle := PThreadParams(p)^.ParentHandle;
  i := 0
  while (i <= 9) and not Abort do
  begin
    SendMessage(ParentHandle, CM_STATUS, LPARAM(PChar('Durchlauf:')), i);
    Sleep(500);
    Inc(i);
  end;
  if i > 9 then
    SendMessage(ParentHandle, CM_FINISHED, 0, 0)
  else SendMessage(ParentHandle, CM_ABORT, 0 , 0);
  Dispose(p);
  Result := 0;
end;
Wobei bei Sowas das Try-Finally, bezüglich des der Speicherfeigabe, sowieso in irgendeiner Weise zu bevorzugen ist.
Delphi-Quellcode:
function DemoThread(p: Pointer): Integer;
var
  i: Integer;
  ParentHandle: THandle;
begin
  try
    ParentHandle := PThreadParams(p)^.ParentHandle;
    i := 0
    while (i <= 9) and not Abort do
    begin
      SendMessage(ParentHandle, CM_STATUS, LPARAM(PChar('Durchlauf:')), i);
      Sleep(500);
      Inc(i);
    end;
    if i > 9 then
      SendMessage(ParentHandle, CM_FINISHED, 0, 0)
    else SendMessage(ParentHandle, CM_ABORT, 0 , 0);
  finally
    Dispose(p);
  end;
  Result := 0;
end;
Abgesehn davon ist der Quatsch mit dem 32-Bit-Integer in 64 Bt hier egal, denn selbst wenn man hier den Pointer ordnungsgemäß in einen 64-Bit-Intreger (in einem 64-Bit-Compiler) umwandelt, dann muß man eh erstmal abgleichen ob dort SendMessage auch 64-Bit-Parameter hat ... also denke ich mal, daß man dort auch gleich den Typen des Parameters nutzen kann.

Und ja, ich finde auch, daß es an einigen Stellen einfach einfacher mit GOTO lösbar ist.
PS: ein Break, While, For, Case und vieles Anderes besteht intern quasi auch nur ein ein paar IFs+GOTO. :angel:

omata 21. Mär 2010 23:03

Re: Sinnvoller Einsatz von goto
 
Zitat:

Zitat von himitsu
Und ja, ich finde auch, daß es an einigen Stellen einfach einfacher mit GOTO lösbar ist.

nicht wirklich, aber wenn du meinst.

Zitat:

Zitat von himitsu
PS: ein Break, While, For, Case und vieles Anderes besteht intern quasi auch nur ein ein paar IFs+GOTO. :angel:

Ja ne, is klar. Wo war nochmal der Unterschied zwischen Hochsprache und Assembler? Ach ja, in einer Hochsprache kann man strukturiert programmieren. GOTO gehört nicht zu den strukturierten Befehlen (Disskussion wie immer, daran ändert sich auch niemals etwas). Nur weil ein Befehl aus historischen Gründen noch existiert, muss man nicht unbedingt auf krampf ein Beispiel konstruieren, damit man auch diesen endlich mal benutzen kann. Das ist einfach unglaublich wie dieses Thema immer wieder hochkocht. Einfach faszinierend und echt traurig.

himitsu 21. Mär 2010 23:16

Re: Sinnvoller Einsatz von goto
 
http://www.delphipraxis.net/internal...062424#1062424
Tut mir ja Leid, aber ohne Goto hätte ich dort so Einiges an doppeltem Code und/oder die eine oder andere Stelle hätte etwas umständlicher gelößt werden müssen.

Und nein, bis auf wenige Stellen nutze ich auch sehr selten ein Goto, also ich kann nicht behaupten, daß ich dieses auf Krampf versuche immer zu verwenden ... wie man oben sieht, geht es auch ja auch oftmals anders/ohne.

Aber bei Rücksprüngen oder beim Rumspringen in mehreren verschachtelten Schleifen ist es schon hier oder da auch mal recht gut zu gebrauchen.

Und wozu soll man etwas Vorhandenes und vorallem Funktionierendes nicht verwenden, wenn es damit "einfacher" geht?

Wenn man weiß, was man macht, dann erzeugt ein Goto auch keinen gefährlichen Code.

omata 21. Mär 2010 23:20

Re: Sinnvoller Einsatz von goto
 
Da reichen vier Buchstaben: Nein

Meflin 22. Mär 2010 01:24

Re: Sinnvoller Einsatz von goto
 
Zitat:

Zitat von omata
Da reichen vier Buchstaben: Nein

:thumb:

Ich bin auch äußerst verwundert über diesen Thread. Gerade von Luckie hätte ich das nicht erwartet :gruebel:

Sinnvoller Einsatz von goto ... ist nicht möglich.

R2009 22. Mär 2010 05:17

Re: Sinnvoller Einsatz von goto
 
Hi,

auch mein Senf dazu:
ich habe noch keinen Fall gesehen indem man goto verwenden müsste!
Auch noch so mühsam konstruierte Fälle kann man mit den üblichen Konstrukten abfangen.

Ansonsten: Alle Jahre wieder kommt das "goto" Kind!

Grüsse
Rainer

alzaimar 22. Mär 2010 07:37

Re: Sinnvoller Einsatz von goto
 
Zitat:

Zitat von R2009
ich habe noch keinen Fall gesehen indem man goto verwenden müsste!

Ich auch nicht, aber die hier gezeigten Alternativen viel schlimmer.
Zitat:

Zitat von R2009
Ansonsten: Alle Jahre wieder kommt das "goto" Kind!

Das ist gut so, denn wie Du siehst, lohnt die Diskussion. Viele Programmierer brechen sich lieber einen ab, als ein GOTO zu verwenden.

Zitat:

Zitat von omata
Da reichen vier Buchstaben: Nein

Wie kannst Du das verneinen? Das ist eine Tautologie!
"Wenn ich weiss, was ich tue, mache ich keine Fehler." Der Satz ist so banal wie: "Wenn es regnet, wird die Erde naß". Den kann man nicht verneinen.

Zitat:

Zitat von omata
...auf krampf ein Beispiel konstruieren, ...

Wo siehst Du hier den Krampf? Mir scheint, Du wurdest in deiner Kindheit von herumlungernden GOTO's verprügelt, anders ist deine Aversion nicht zu erklären. Lies doch nochmal den Threadanfang: Michael stellt eine Behauptung auf und lädt zur Diskussion ein. Persönlich und diffamierend muss man da nicht werden, auch wenn man als Bub von GOTO's gequält wurde. Wie sagtest Du so schön, das ist bedauernswert
Zitat:

...und echt traurig.
:zwinker:

Zitat:

Zitat von himitsu
Delphi-Quellcode:
function DemoThread(p: Pointer): Integer;
...
    if Abort then begin
      SendMessage(ParentHandle, CM_ABORT, 0 , 0);
      Break;
    end;
    SendMessage(ParentHandle, CM_STATUS, Integer(PChar('Durchlauf:')), i);
    Sleep(500);
    if i = 9 then SendMessage(ParentHandle, CM_FINISHED, 0, 0);
  end;
  Dispose(p);
  Result := 0;
end;

Das soll lesbarer sein? Dieser Code ist Vieles, aber eines sicherlich nicht: Lesbarer. Und intuitiv zu erfassen ist er auch nicht, denn ich muss mir erst überlegen, was die komische IF-Anweisung in der Schleife soll. Die wird bei jedem(!) Schleifendurchlauf ausgeführt, nur um beim letzten Mal (und nur dann!) TRUE zu liefern. Uneffizienter und Umständlicher kann man kaum kodieren. Und das alles nur, um ein GOTO zu vermeiden? Nebenbei ein eklatanter Verstoß gegen das DRY-Prinzip: Die zentrale Bedingung (max. N Versuche) ist an zwei Stellen im Code).

In diesem Thread geht es nicht darum zu zeigen, wie man ein GOTO vermeidet (ich unterstelle Michael mal, das er weiss, wie das geht), sondern um die Frage, ob Code mit einem GOTO nicht manchmal lesbarer wird!

Der zweite Versuch von Dir ist ein Paradebeispiel für Codeencryption :mrgreen: .
Delphi-Quellcode:
...
  while (i <= 9) and not Abort do ...
Ich verwende diese While-Schleife immer wieder gerne als Beispiel, wieso ein Sprung (Break, Exit, und die Verwendung einer eigenen Funktion) sinnvoller ist, als das umständliche Hantieren mit Schleifen und Abbruchbedingungen.

Zitat:

Und ja, ich finde auch, daß es an einigen Stellen einfach einfacher mit GOTO lösbar ist.
Ah :thumb:

Ich behaupte aber mal als Konsequenz (um auch eine Brücke zu omata zu schlagen):
1. Jedes einigermaßen nachvollziehbare GOTO springt aus einer Schleife heraus. Andere sinnvolle Verwendungen gibt es nicht.
2. Jede Schleife kann in eine Funktion (SRP) verfrachtet werden, wodurch das GOTO durch ein EXIT ersetzt werden kann.
3. Ergo kann man GOTO streichen, ohne die Lesbarkeit des Codes zu verschlechtern.
4. Im Umkehrschluss kann Code lesbarer werden, wenn kein GOTO verwendet wird.

(4) Gilt aber nicht automatisch und immer, wie man an den vielen Alternativen hier gesehen hat!

So, und wer nun kein Anhänger des 'Clean Code' ist und nicht immer Bock hat, jede Pupsschleife in eine eigene Funktion zu packen, nur um ein GOTO zu vermeiden, der soll in Gottes Namen sein GOTO verwenden. Davon geht die Welt nicht unter. Der Code bleibt effizient und vor allem wesentlich lesbarer, als jeder krampfhafte Versuch, mit Flags und While-Schleifen ein GOTO zu vermeiden.

Deep-Sea 22. Mär 2010 08:04

Re: Sinnvoller Einsatz von goto
 
Noch mal eine Kleinigkeit, die ggf. gegen ein Goto spricht: Da es nicht in allen Sprachen existiert (z.B. in Java), lässt sich ein Quelltext mit Goto schlechter in solche Sprachen portieren, weil man den Code dazu verstehen (was natürlich immer von Vorteil ist) und auch ändern muss :lol:
(Klar, euch kann es egal sein, ob andere Programmierer die einen guten Code gerne auf "ihre" Sprache portieren möchten sich dazu abplagen müssen oder nicht ...)

Wolfgang Mix 22. Mär 2010 09:29

Re: Sinnvoller Einsatz von goto
 
Wikipedia meint:

Zitat:

Pascal unterstützt in seiner Urform keine Anweisungen, mit denen Prozeduren
oder Schleifen hart verlassen werden können. Als strukturerhöhendes goto
werden Sprünge ans Ende von Prozeduren oder unmittelbar hinter Schleifenenden
akzeptiert, sofern sich dadurch umfangreiche Konstruktionen schlecht
lesbarer if-Anweisungen oder undurchschaubarer boolescher Ausdrucke
vermeiden lassen. Viele Pascal-Compiler erlauben keine goto, die zu instabilen
Systemzuständen führen, z. B. der Sprung in den Anweisungsblock einer Schleife
oder eines if.
Dieses Beispiel habe ich im Handbuch von TP 5.5 gefunden. Passt wunderbar zum Thema
Lösung quadratischer Gleichungen mit der Hochzeitsformel, wenn a 0 ist.
Delphi-Quellcode:
VAR A,B,C : Integer;
Label : Ende;
Begin
  Anweisungen ...
  Readln(A);
  If (A=0) Then Goto Ende;
  Anweisungen ...
  Ende: {Hier ist das Label Ende}
  Writeln('Hier ist wirklich Schluß');
End.
Dann löst das 'mal komplizierter ...

Deep-Sea 22. Mär 2010 09:38

Re: Sinnvoller Einsatz von goto
 
Zitat:

Zitat von Wolfgang Mix
Delphi-Quellcode:
VAR A,B,C : Integer;
Label : Ende;
Begin
  Anweisungen ...
  Readln(A);
  If (A=0) Then Goto Ende;
  Anweisungen ...
  Ende: {Hier ist das Label Ende}
  Writeln('Hier ist wirklich Schluß');
End.

Delphi-Quellcode:
VAR A,B,C : Integer;
Begin
  Anweisungen ...
  Readln(A);
  If A <> 0 then
  begin
    Anweisungen ...
  end;
  Writeln('Hier ist wirklich Schluß');
End.
:?:
Oder wie oder was???

DeddyH 22. Mär 2010 09:48

Re: Sinnvoller Einsatz von goto
 
IIRC gab es in TP < 7 weder break noch exit, daher waren gotos die einzige Möglichkeit, aus einer Schleife herauszuspringen. Ansonsten stört mich weder break, exit noch goto, wenn es sinnvoll und spärlich eingesetzt wird und der Lesbarkeit dient. So, die ewig Gestrigen können mich jetzt meinetwegen steinigen.

[edit] Kleine Korrektur: eine Möglichkeit gab es doch mit dem Einsatz einer Boolschen Variablen, die gesetzt werden konnte, um die Schleife zu verlassen, aber das war doch ziemlich umständlich IMO [/edit]

Progman 22. Mär 2010 10:12

Re: Sinnvoller Einsatz von goto
 
Programmieren ist eine Tätigkeit, die schöpferisch und sehr individuell von Statten geht.
Jeder hat Vorlieben oder Aversionen auf Grund seiner Erfahrung, was die Codierung betrifft. Und niemand muss sich zu irgendwelchen "Programmier-Stil-Standards" zwingen lassen.
Also soll doch bitteschön niemand meckern, wenn jemand in bestimmten Situation auch zu "verpönten" Befehlen wie Goto, Exit, Break, Halt usw. greift. Die Hauptsache ist, dass das Programm fehlerfrei läuft. Den Anwender interessiert es herzlich wenig, was im Quell-Code steht. :-D

Luckie 22. Mär 2010 10:37

Re: Sinnvoller Einsatz von goto
 
Zitat:

Zitat von Progman
Die Hauptsache ist, dass das Programm fehlerfrei läuft.

Nein auch Wartbarkeit spielt eine Rolle. Und damit ein Code wartbar ist, muss er lesbar und möglichst leicht verständlich sein. Ein wildes hin und her Gespringe mit goto und ähnlichen Konstrukten, ist da eher kontraproduktiv.

Matze 22. Mär 2010 10:51

Re: Sinnvoller Einsatz von goto
 
Zitat:

Zitat von Progman
Und niemand muss sich zu irgendwelchen "Programmier-Stil-Standards" zwingen lassen.

Das stimmt auch nicht ganz. Wenn der Arbeitgeber einen Styleguide festlegt, dann muss man sich daran halten.
Ist dort festgelegt, dass ein "goto" nicht verwendet werden darf, ist man gezwungen, dieses auch nicht einzusetzen.

Progman 22. Mär 2010 12:50

Re: Sinnvoller Einsatz von goto
 
Zitat:

Zitat von Luckie
Zitat:

Zitat von Progman
Die Hauptsache ist, dass das Programm fehlerfrei läuft.

Nein auch Wartbarkeit spielt eine Rolle. Und damit ein Code wartbar ist, muss er lesbar und möglichst leicht verständlich sein. Ein wildes hin und her Gespringe mit goto und ähnlichen Konstrukten, ist da eher kontraproduktiv.

An wildes hin- und hergespringe habe ich da eigentlich nicht gedacht. Aber es sind Konstrukte denkbar, wo Code mit einem Goto wesentlich besser lesbar (und wartbar) ist als künstliche Verrenkungen, nur um kein Goto zu verwenden. Aber das wurde hier ja auch schon gesagt ;)
Und dass ein Arbeitgeber vorgibt, in welchem Stil programmiert werden muss, hab ich noch nie gehört.
Es gibt meist Vorgaben für die Software (was sie können muss, wie sie aussehen und gestaltet sein soll etc.).
Dem Auftraggeber ist es meist sogar egal, in welcher Sprache gearbeitet wird. Hauptsache seine Vorgaben werden erfüllt.
Wir machen Software, die verkauft werden soll und nicht, welche um den besten Programmierstil wetteifert. Das intrweressiert den Käufer nicht die Bohne *g*

himitsu 22. Mär 2010 12:57

Re: Sinnvoller Einsatz von goto
 
Zitat:

Zitat von Progman
Und dass ein Arbeitgeber vorgibt, in welchem Stil programmiert werden muss, hab ich noch nie gehört.

Das bezog sich vorwiegend auf Softwarefiremen wo der Programmierer dann angestellt wäre und wo dann womöglich auch noch Mehrere an dem Projekt arbeiten.
Dort gibt es oftmals entsprechende Vorgaben, damit der Code innerhalb der Firma "gleich" aussieht und damit natürlich auch alle den Code dann besser verstehen können.
> also meist existiert da ein entsprechender Style-Guide

Neutral General 22. Mär 2010 13:01

Re: Sinnvoller Einsatz von goto
 
Vor allem ist "Auftraggeber" nicht unbedingt gleich "Arbeitgeber"!

Dem Auftraggeber kann der Code und die verwendete Programmiersprache egal sein. Dem Arbeitgeber aber noch lange nicht!

Luckie 22. Mär 2010 13:01

Re: Sinnvoller Einsatz von goto
 
Zitat:

Zitat von Progman
Und dass ein Arbeitgeber vorgibt, in welchem Stil programmiert werden muss, hab ich noch nie gehört.

Natürlich gibt es firmeninterne Styleguides, wie Code zu formatieren ist. Vielleicht nicht in jeder Firma aber in größeren bestimmt. Und wenn man im Team arbeitet ist es fast unumgänglich, dass man sich da einigt.

Zitat:

Dem Auftraggeber ist es meist sogar egal, in welcher Sprache gearbeitet wird. Hauptsache seine Vorgaben werden erfüllt.
Richtig.
Zitat:

Wir machen Software, die verkauft werden soll und nicht, welche um den besten Programmierstil wetteifert. Das intrweressiert den Käufer nicht die Bohne *g*
Dann viel Spass, wenn der Kund ein zwei Jahren wiederkommt und etwas geändert haben will. Und wenn dann noch der ursprüngliche Programmierer nicht mehr da ist, kann das ziemlich teuer werden für euch, wenn man sich da erst stundenlang einarbeiten muss, um den Quelltext zu verstehen. Klar, wenn ich den Code einfach nur hinrotze und nur zu sehe, dass er irgendwie läuft, egal wie, bin ich zwar schnell und kostengünstig fertig, aber später wird man da um so mehr drauflegen.

Hansa 22. Mär 2010 13:17

Re: Sinnvoller Einsatz von goto
 
Äh, merkt denn hier keiner, dass über den Schnee von vor 40 Jahren diskutiert wird ? :shock: Alle Jahre wieder oder was ? :zwinker: Ich vermute mal, dass das Goto lediglich im Ur-Pascal vorhanden war, damit Umsteiger von Basic nicht direkt an neueren Schleifen etc. scheitern. That's it. Exit gabs übrigens schon vor BP 7. Hatte das auch gern eingesetzt. Irgendwann hatte ich dann aber gemerkt, dass es mehr ärgerliche Quereffekte verursacht, als es wert ist. Was heisst nun sinnvoll ? IMHO, auf diesen uralten goto-Firlefanz grundsätzlich zu verzichten. 8-) Warum soll man etwas mit goto machen, nur weil es auch gehen würde ? Vorteile hat es jedenfalls keine. Ausser, sich darüber zu streiten, was nun lesbarer ist ? Wenn mir ein Beispiel-Quelltext auf den Tisch käme, der mehr als 0 gotos beinhaltet, dann womöglich direkt -> Tonne. :mrgreen:

Progman 22. Mär 2010 13:26

Re: Sinnvoller Einsatz von goto
 
Zitat:

Zitat von Luckie
Zitat:

Zitat von Progman
Und dass ein Arbeitgeber vorgibt, in welchem Stil programmiert werden muss, hab ich noch nie gehört.

Natürlich gibt es firmeninterne Styleguides, wie Code zu formatieren ist. Vielleicht nicht in jeder Firma aber in größeren bestimmt. Und wenn man im Team arbeitet ist es fast unumgänglich, dass man sich da einigt.

Zitat:

Dem Auftraggeber ist es meist sogar egal, in welcher Sprache gearbeitet wird. Hauptsache seine Vorgaben werden erfüllt.
Richtig.
Zitat:

Wir machen Software, die verkauft werden soll und nicht, welche um den besten Programmierstil wetteifert. Das intrweressiert den Käufer nicht die Bohne *g*
Dann viel Spass, wenn der Kund ein zwei Jahren wiederkommt und etwas geändert haben will. Und wenn dann noch der ursprüngliche Programmierer nicht mehr da ist, kann das ziemlich teuer werden für euch, wenn man sich da erst stundenlang einarbeiten muss, um den Quelltext zu verstehen. Klar, wenn ich den Code einfach nur hinrotze und nur zu sehe, dass er irgendwie läuft, egal wie, bin ich zwar schnell und kostengünstig fertig, aber später wird man da um so mehr drauflegen.

Nunja, wir sind nur eine kleine Firma und wir haben nur 2 Programmierer. Ich arbeite in Delphi während der andere alles andere (Flash etc.) macht und das seit über 10 Jahren. Mein Chef ist damit beschäftigt, ständigen Kontakt mit unseren Auftraggebern zu halten, so dass wir immer zu tun haben. Die Programme, die ich mache bzw. betreue, erfahren jedes Jahr eine Neuauflage (Design, manchmal auch Inhalt). Und ich gestalte meinen Code, wie ich es für sinnvoll halte. Wir machen halt Software, die nicht gewartet werden muss, da sie eh jedes Jahr neu gemacht wird.
Daher ist eben für mich dieses "Programmieren nach Vorschrift" irrelevant ;)

Luckie 22. Mär 2010 13:50

Re: Sinnvoller Einsatz von goto
 
Auch wenn es langsam offtopic wird, aber nur damit ich das richtig verstehe. Du schreibst jedes Jahr das komplette Programm neu, wenn der Kunde etwas geändert oder erweitert haben will? Kannst du mir mal bitte sagen, was das soll und warum du das machst?

Progman 22. Mär 2010 14:24

Re: Sinnvoller Einsatz von goto
 
Zitat:

Zitat von Luckie
Auch wenn es langsam offtopic wird, aber nur damit ich das richtig verstehe. Du schreibst jedes Jahr das komplette Programm neu, wenn der Kunde etwas geändert oder erweitert haben will? Kannst du mir mal bitte sagen, was das soll und warum du das machst?

Ich schreibe es nicht neu sondern gestalte es neu (meist nur äußerlich). Der "Code-Kern" bleibt gleich. Es gibt einfach jedes Jahr eine Neuauflage.
Und dass ein Kunde (das wäre in diesem Fall z.B. ein MediaMarkt-Kunde, der das Teil für 9,99 gekauft hat) etwas geändert haben wollte, ist noch nie vorgekommen. Wäre ja auch irgendwie absurd *g*
Zumal die Programme unter dem Namen unseres Auftraggebers erscheinen und unsere Firma da eigentlich unerwähnt ist.

Tyrael Y. 22. Mär 2010 15:30

Re: Sinnvoller Einsatz von goto
 
Wenn es um die Lesbarkeit geht ist folgende Variante, angelehnt ans Cristian Seehase´s Version noch lesbarer.

Delphi-Quellcode:
function DemoThread(const AParentHandle : THandle): Integer;
var
  i: Integer;
begin
  for i := 0 to 9 do
  begin
    if Abort then
    begin
      SendAbort(AParentHandle );
      break;
    end else
    begin
      SendStatus(AParentHandle, i);
      Sleep(500);
    end;
  end;

  if not Abort then
  begin
    SendFinished(AParentHandle);
    Result := 0;
  end;
end;

procedure SendAbort(const AParentHandle : THandle);
begin
  SendMessage(AParentHandle, CM_ABORT, 0 , 0);
end;

procedure SendStatus(const AParentHandle : THandle; index: Integer);
begin
  SendMessage(AParentHandle, CM_STATUS, Integer(PChar('Durchlauf:')), index);
end;

procedure SendFinished(const AParentHandle : THandle);
begin
  SendMessage(AParentHandle, CM_FINISHED, 0, 0);
end;
Jeder soll programmieren wie er selber meint den Code am Besten lesen zu können, denn in 80% der Fälle wird der Verfasser auch den Code lesen.

himitsu 22. Mär 2010 16:09

Re: Sinnvoller Einsatz von goto
 
Zitat:

Zitat von Tyrael Y.
Wenn es um die Lesbarkeit geht ist folgende Variante,

Wenn ich mich nicht irre, sollte der Compiler hier etwas vonwegen "Result könnte undefiniert sein" von sich geben.

shmia 22. Mär 2010 17:26

Re: Sinnvoller Einsatz von goto
 
Noch etwas Öl oder Code für's Feuer. :stupid:
Also ich habe bei dieser Funktion noch keinen Weg gefunden, es ohne Goto elegant zu formulieren.
Delphi-Quellcode:
// Prüft, ob eine Datei für den Import vorhanden ist.
// Falls nicht, kann der Benutzer entscheiden, was passieren soll
function CheckImportFile(const fname: TFilename; const Caption:string): Boolean;
var
   msg: string;
label again;
begin
   again:
   if not FileExists(fname) then
      msg := Format('Datei <%s> ist nicht vorhanden', [fname])
   else if FileGetSize(fname) = 0 then
      msg := Format('Datei <%s> ist leer', [fname])
   else
      msg := '';

   if msg <> '' then
   begin
      case MessageBox(0, PChar(msg), PChar(Caption), MB_ICONWARNING or MB_ABORTRETRYIGNORE or MB_SETFOREGROUND) of
        idAbort: Abort; // stille Exception
        idRetry: goto again;
        idIgnore:
        begin
           Result := False; // Datei vorhanden oder leer; der Benutzer möchte die Datei ignorieren
           Exit;
        end;
      end;
   end;
   Result := True; // Datei vorhanden und nicht leer
end;


Alle Zeitangaben in WEZ +1. Es ist jetzt 14:41 Uhr.
Seite 1 von 2  1 2      

Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz