Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Sommerloch...

2 views
Skip to first unread message

Robert H. Hanko

unread,
Jul 20, 1996, 3:00:00 AM7/20/96
to

Hallo Michael,

MH> Und da man goto nicht braucht, ...

MH> Im Prinzip reicht while als Schleifenkonstrukt.

Ich habe das auch schon versucht. Aber ich komme nicht
ganz klar damit. Wenn ich nun 2 verschachtelte Schleifen
habe und mit der inneren beide abbrechen moechte. Wie bitte
muss ich das erstellen ohne goto zu verwenden? (Ich bin leider
Anfaenger und habe das Problem - fuer mich - noch nicht
loesen koennen).

Mit freundlichen Gruessen
Robert

--- Maximus 3.01
* Origin: Online: 22:00 - 08:00 ++43-1-523 52 85 (V.34/V.FC) (2:240/4150.3)

Soenke Mueller-Lund

unread,
Jul 21, 1996, 3:00:00 AM7/21/96
to

Moin Erhard,

ES>>> Es ist inzwischen mathematisch nachweisbar, dass _jede_
ES>>> Aufgabenstellung, die ueberhaupt loesbar ist, auch ohne GOTO loesbar
ES>>> ist.

MR>> Ja. Klar. Es ist auch nachweisbar, das _jede_ Aufgabenstellung, die
MR>> ueberhaupt loesbar ist, auch ohne Pascal loesbar ist. =8-)=)

> Das geht aber am Problem vorbei.

auch wenn ich es ungern tue, hier muß ich Michael recht geben.

ES>>> GOTO ist ein
ES>>> Befehl, der in keinem, aber absolut keinem Programm irgendeine
ES>>> Berechtigung haette.

MR>> ... und damit geht die Diskussion in die theologische Ebene ueber. Ich
MR>> sehe diese Sache viel relaxter: Wenn Du goto brauchst, nimmst Du goto.

> Du brauchst es eben nicht. Wenn du ein goto (scheinbar) brauchst, ist das
> schon ein Beweis fuer ein mangelhaftes Design, wenn du das Goto nicht durch
> eine saubere if- oder while-Konstruktion ersetzen kannst.

Wozu sich diese erzieherischen Pascal-Thesen aufladen?
Die Anweisungen break, continue und return (inmitten der Funktion) sind
eigentlich nichts anderes, als versteckte goto's, da sie den Block auf
"unnatürlichem" Wege verlassen. In C++ heißen die neuen goto's
"Exceptions". ;)

MR>> PS: Die Formulierung ist zwar nicht von mir, aber man koennte "for,
MR>> while, do-while, continue, break und derlei Dinge mehr als goto's im
MR>> Abendkleid betrachten".

So ist es.

> Koennte man schon. Aber diese goto's kannst du ja direkt ersetzen. Und
> "andere" goto's sind eben kapitale Strukturfehler im Design. Und da ist das
> Problem. Das Design muss zu 250% gut sein, sonst hast du nachher immense
> Schwierigkeiten mit Wartung und Pflege. Das faengt unter Umstaenden schon
> beim Debuggen an!

Willst Du ein Programm fertigstellen, oder willst Du für deine Sourcen
Schönheitspreise gewinnen?

In vielen Fällen ist der Aufwand einfach nicht gerechtfertigt, ein goto
durch einen anderen Konstrukt zu ersetzen.

Ciao
Sönke

PS: goto habe ich selbst erst 2x benutzt.

"My homepage is my castle"

Herbert Rosenau

unread,
Jul 21, 1996, 3:00:00 AM7/21/96
to

Hi Robert,

am 20.07.96 10:46 erzähltest Du Michael

RHH> Ich habe das auch schon versucht. Aber ich komme nicht ganz klar
RHH> damit. Wenn ich nun 2 verschachtelte Schleifen habe und mit der
RHH> inneren beide abbrechen moechte. Wie bitte muss ich das erstellen ohne
RHH> goto zu verwenden? (Ich bin leider Anfaenger und habe das Problem -
RHH> fuer mich - noch nicht loesen koennen).


int fertig = FALSE;

for (/*init*/; !fertig && (/*abbruchbedingung*/); /*Abschluß*/) {

/* igendwas */

for (init; /*abbruchbedingung*/; /*Abschluß*/) {

/* irgendwas */

if (fehler) { fertig = TRUE; break;

/* noch was */
}
/* noch was, das IMMER gemacht werden soll */
/* kann auch fehlen */

if (fertig) continue; /* break; geht auch */

/* noch mehr code */

}

if (!fertig) {
/* die Schleifen wurden BEIDE bis zum Ende bearbeitet */
} else {
/* die innere Schleife wurde vorzeitig abgebrochen */
}


Tschau/Bye

Herbert email: h...@softpro.de
Member #53 of Team/OS2 Germany
--- Sqed/32 1.12/r00196
* Origin: Schont die Umwelt: Vermeidet DOSen (2:2476/493)

Erhard Schwenk

unread,
Jul 21, 1996, 3:00:00 AM7/21/96
to

Hallo Michael!

MR> Ausserdem zeigt es sehr schoen, dass man Dinge, die "theoretisch" nicht
MR> gebraucht werden, in der Praxis recht nuetzlich sein koennen. Wie goto.
MR> Oder Pascal =8-)=)

Das goto brauchst du aber eben auch in der Praxis nicht.

MR> Beispiel: Aus irgendwelchen Gruenden hast Du 'ne ganze Reihe von
MR> Funktionen, die im Fehlerfall immer die Befehlssequenz bla-laber-blubb
MR> abarbeiten muessen. Solche Fehler koennen an mehreren Stellen innerhalb
MR> einer Funktion auftreten, so dass jedesmal bla-laber-blubb faellig wird.

MR> Nun koennte die Sache mit folgender Struktur uebersichtlicher gestalten:

MR> DieseFunktion ( ... )
MR> {
MR> if(ParameterUngueltig)
MR> goto DieseFunktion_ErrOut;
MR> ...
MR> if(BaggerseeZuKalt)
MR> goto DieseFunktion_ErrOut;
MR> ...

MR> return AllesEasyEy;

MR> DieseFunktion_ErrOut:
MR> bla;
MR> laber;
MR> blubb;
MR> return Fehlercode;
MR> }

MR> Auch im Fehlerfall hat diese Funktion dann formal nur einen Ausgang (altes

MR> Design-Prinzip einmal anders... thihi...)

Das macht man erstens mal viel eleganter ueber ein paar Praeprozessor-Makros.
Die Konstruktion, die du anwendest, ist zweitens formal nichts anderes als eine
break-Konstruktion. Und drittens: Wenn du von vorneherein mit ner richtigen
Analysemethode arbeitest, ist diese Konstellation gar nicht moeglich. Es geht
gar nicht, beispielsweise mit SA so eine Konstruktion zu erzeugen, weil du
bereits in der Analysephase auf einen ganz anderen Weg kommen wirst.

MR> Noe. Eher fuer ein falsch definiertes "richtiges Design".
MR> "Zu enge Kopplung" der Begriffe "goto" und "richtiges Design". (ooops -
MR> schon wieder ein geklautes Prinzip)

Eben nicht. Wenn du strukturierte Designmethoden verwendest (Beispiel: SADT
oder im Datenbankbereich die Methode von Scheer) kannst du ueberhaupt nicht auf
ein goto kommen. Ein goto laesst sich mit diesen Methoden naemlich nicht
darstellen. Da du z.B. bei SA am Schluss in der Mini-Spez ueblicherweise mit
Nassi-Shneidermann-Diagrammen arbeitest, fliegen solche Dinge bereits in der
Phase raus. Wenn du dann trotzdem ein goto einsetzt, hast du was anderes
programmiert als du designt hast - auch wieder ein strukturfehler. Selbst das
beliebte "break" kann in einem solchen Fall gar nicht entstehen, weil es vom
Design schlicht nicht vorgesehen (und auch nicht gebraucht!) wird.

MR> Na ja... wer zum Beispiel die obige Funktionsstruktur nicht versteht, hat

MR> imho ganz andere Probleme...

Wenn die Funktion in ein groesseres Projekt eingebettet ist, ist das recht
schnell sehr unverstaendlich. Du musst mal ueber den Tellerrand von
30-Zeilen-Programmen raussehen.

MR> Noe. Du machst keine Fallunterscheidung. Das ist das Problem. Der
MR> Zeitaufwand lohnt sich nicht, wenn's um Quickies geht.

Quickies haben in professionellen Entwicklungen nichts zu suchen. Eben
aufgrund der Lebensdauer der Software. Ich erleb das grad selber im Geschaeft.
Man macht ne Q&D-Loesung fuer irgend ein Problem, dann wird da jahrelang dran
angestueckelt und am Schluss hast du einen riesen Oschi von Muell-Code, der
noch nicht mal sauber dokumentiert ist. Aber mit Software Engineering hat das
dann nichts mehr zu tun. Und da entstehen dann die Probleme. Anstatt dass man
sich gleich am Anfang mal hinsetzt und eine ordentliche Analyse und ein
ordentliches Design macht, was effektiv auf die Dauer betrachtet um mindestens
den Faktor 10 billiger kommt.

MR> Manche Quickies wie z.B. Unix sind immer noch in Gebrauch. Stimmt.

Eben.

MR> Noe. Mit goto rettet man sich normalerweise aus einer verzwickten Lage
MR> heraus, die anderweitig nur durch komplexe Umstellungen im Code zu
MR> bewaeltigen waere (Zeit, Kosten, fehleranfaellig).

So eine Lage entsteht bei einem ordentlichen Design eben gar nicht erst, das
ist ja gerade der Gag. Wenn du da hinkommst, hast du bereits einen Fehler
bewiesen. Und den nur zu umschiffen ist nicht nur unsauber, sondern auch
gefaehrlich, denn du hast dann auch keine Garantie mehr dafuer, dass dein
Design ueberhaupt funktioniert.

MR> Wenn im Design schon ersichtlich ist, ob irgendwo gotos auftauchen oder
MR> nicht, ist es nicht abstrakt genug.

In einem guten Design nach einer strukturierten Methode (wenns nicht grad
Jackson oder HIPO ist) kann kein goto auftauchen. Dazu ist das Design da. Was
du meinst, ist die Analysephase, die tatsaechlich sehr abstrakt ist. Aber
selbst da steht (zumindest z.B. bei SA) am Schluss bereits ne
Mini-Spezifikation, und im Design werden bei einigen Methoden sogar
Hardware-Anforderungen oder aehnliches festgehalten. Das Design soll nicht
abstrakt sein, sondern die konkrete Problemloesung lediglich unabhaengig vom
verwendeten Werkzeug (Sprache, Rechnerumgebung etc.) darstellen. Und Da
erkennst du sehr wohl, ob du ein goto brauchst oder nicht. Ein vollendetes
Design waere z.B. eine Reihe von Struktogrammen, die die einzelnen Funktionen
des Programms beschreiben, in Verbindung mit einem Data Dictionary, das die
Datenbestaende und -Verbindungen bzw. Beziehungen aufzeigt (z.B. in Form eines
ER-Modells). Da kannst du jede Zeile Code direkt draus ablesen. Und die
Implementierung beschraenkt sich dann absolut auf das Umsetzen des Designs in
eine konkrete Umgebung. Das ist bei einem guten Design normalerweise eine
schlichte Uebersetzungsarbeit.

ES>> Das faengt unter
ES>> Umstaenden schon beim Debuggen an!

MR> Ich habe in meiner Schublade ein nettes kleines Prograemmelchen, das
MR> wuerde ohne goto noch nicht mal den Weg bis in den Debugger schaffen.

MR> (Genauer gesagt, die goto's sind so abgedreht, dass ich sie nur in
MR> Assembler schreiben konnte - es trifft's also eigentlich nicht genau. Aber

MR> Du kannst Dich drauf verlassen, dass diese Spruenge aus der Sicht der
MR> Struktur-Paepste genauso "igittebah" sind wie goto :)

MR> Hm - beim Greppen stiess ich gerade auf folgende Zeile:

MR> goto ICantBelieveIUsedAGoToStatement;

MR> :),

MR> Michael


MR> -!- CrossPoint v3.02 R
MR> ! Origin: Du kannst ueberholen... die Wolken brechen auf...
(2:2453/30.77)

MfG, Erhard!

--- FleetStreet 1.12.1 NR
* Origin: Gib GATES keine Chance =)B==o) (2:2487/3001.65)

Erhard Schwenk

unread,
Jul 22, 1996, 3:00:00 AM7/22/96
to

Hallo Rainer!

ES>> Du brauchst es eben nicht. Wenn du ein goto (scheinbar)
ES>> brauchst, ist das schon ein Beweis fuer ein mangelhaftes
ES>> Design,

RH> Nope. Ich benutze GOTO zu genau einem Zweck: im Fehlerfall Sprung zum
RH> Funktionsende. Das ist IMHO lesbarer als zig if/case Konstrukte, die
RH> dann alle direkt vor dem return terminieren.

So, und wenn du dann an einer bestimmten Stelle zwischen deinem goto und dem
Funktionsende noch was einfuegen musst, was auch im Fehlerfall zur Ausfuehrung
kommen soll, dann kannst du deine ganze Implementierung ueber den Haufen
schmeissen. Uebersichtlich wird das ganze uebrigens einfach dadurch, dass man
die Laenge der einzelnen Funktionen auf 30-50 LOC beschraenkt (ausgenommen
Tabellenfunktionen, die nur aus einem einzigen langen Case-Konstrukt bestehen
oder andere derartige "Fleiss"-Funktionen, die strukturell nur einen Block
haben). Die if/case-Konstrukte sehen wirklich auf den ersten Blick umstaendlich
aus, aber wenn du nachher weitere Unterscheidungen einbauen musst, hast du es
mit denen viel leichter, als wenn du mit goto's kaempfen musst, die du nach x
Jahren sehr wahrscheinlich gar nicht mehr alle findest.

Michael Hohner

unread,
Jul 22, 1996, 3:00:00 AM7/22/96
to

Hallo Robert!

Am 20.07.96 schrieb Robert H. Hanko:

RHH> Wenn ich nun 2 verschachtelte Schleifen
RHH> habe und mit der inneren beide abbrechen moechte. Wie bitte
RHH> muss ich das erstellen ohne goto zu verwenden?

int ende1=0;

while (!ende1 && weitere_bedingungen)
{
...
while (bedingungen)
{
...
if (ende_bedingung)
{
ende1=1;
break;
}
...
}
}


Servus, Michael.

--- FleetStreet 1.16.1+
* Origin: FleetStreet - where I want to go today (2:2490/2520.17)

kris

unread,
Jul 23, 1996, 3:00:00 AM7/23/96
to

Erhard_...@p65.f3001.n2487.z2.fidonet.org (Erhard Schwenk) writes:
>Also, Kerninghan hat ja sicher recht, dass manchmal laengerer Code entsteht.
>Aber dieser ist kaum ineffektiver und ausserdem sauberer strukturiert.

Nur dass die Struktur eines Programmes kein Selbstzweck ist.

Genaugenommen ist es total schnurz, ob Dein Programm
strukturiert ist - das Designziel, das erreicht werden soll ist
nicht "Struktur des Quelltextes", sondern "Leichte Wartbarkeit"
und "Uebersichtlichkeit". Die Struktur ist dabei nur ein Mittel
zur Erreichung dieses Zweckes, aber keine hl. Lehre. Das
verlieren die Verfechter von reinem ISO-Pascal manchmal aus den
Augen.

Und unter diesem Kritierium schneidet Pascal dann gelegentlich
nicht besonders gut ab. Wie Kernighan demonstriert, fuehrt die
Armut an solchen verkuerzenden Kontrollstrukturelementen wie
"break" dazu, dass Programmierer aus Bequemlichkeit auf die
korrekte, langatmige Formulierung des Codes verzichten.
Stattdessen schreiben sie die verkuerzte, aber leider unter der
Auswertungsreihenfolge von ISO-Pascal *falsche* Form hin.

Das ist ja dann auch genau der Grund, warum man in Turbo-Pascal
Dinge wie short circuit evaluation, Schleifenabbrueche und so
weiter als Sprachelemente eingefuehrt hat: Damit aus einer
Wandtafelsprache eines Algorithmenprofessors ein Werkzeug wird,
das im taeglichen Gebrauch ueberleben kann.

>Die einzige Stelle, wo in meinen Augen ein break in C-Code was zu suchen hat,
>ist deshalb in der switch()-Konstruktion.

Konstrukte wie

funktion()
{
error_t error;
result_t result;

if (!waechter) {
error = GRUNDa;
return error;
}
if (!waechter2)
error = GRUNDb;
return error;
}

while(arbeitsbedingung)
{
if (fehler)
{
error = GRUND1;
goto errorhandler;
}
if (anderer fehler)
{
error = GRUND2;
goto errorhandler;
}
arbeitsanweisungen;
}

return result;

errorhandler:
handle(&error);
return error;
}

sind gaengige Redewendungen in C und das seit Jahrzehnten.
Programmcode dieser Form zieht sich zum Beispiel durch von den
Quellen fuer den UNIX V7 Kernel und die dazugehoerenden
Utilities bis hin zu aktuellen Versionen von 4.4BSD und Linux.
Und das, obwohl sich der Programmierstil ansonsten ziemlich
radikal gewandelt hat (das ist eine andere, nicht minder
interessante Geschichte).

Solche Redewendungen sind ausserdem auch sehr uebersichtlich,
weil sie naemlich die Fehler- und Abbruchbedingungen, auf die
getestet wird, in einer leicht zu lesenden und auch raeumlich
zusammengehoerenden Form aufschreiben.

Wenn das nicht in die Ideologie der sogenannten strukturierten
Programmierung passt, dann ist das ein Grund, ueber die
Leistungsfaehigkeit dieser Ideologie nachzudenken. Auch das ist
getan worden. Das Resultat ist zum Beispiel das formalisierte
Exception-Handling in Objective-C, C++, Java oder den
Microsoft-C-Erweiterungen (siehe Jeffrey Richter, "Advanced
Windows", Microsoft Press, Kapitel 14, "Structured Exception
Handling").

In allen diesen Sprachen werden sehr aehnliche Konstrukte zur
Handhabung dieses extrem haeufigen Spezialfalls vorgestellt,
die ueber das o.a. Beispiel noch hinausgehen und die nach den
Prinzipien der "strukturierten Programmierung" boese sind.

Das dem so ist, ist nicht verwunderlich. "Strukturierte
Programmierung" ist ein Konzept aus den Zeiten von BASIC, COBOL
und FORTRAN (man sehe sich an, von welchem Datum "GOTO's
considered harmful" ist). Damals war das Hauptproblem, Code so
ans Rennen zu bekommen, dass er ueberhaupt Leistung brachte.
Dieses Problem wurde von den Informatik-Schlipstraegern damals
als "die Softwarekrise" bezeichnet.

Heute hat man mit der Erzeugung von laufendem Code und dem
Verstaendnis von grundlegenden Kontroll- und Datenstrukturen
keine Probleme mehr. Die heutige "Softwarekrise" (ja, dieses
Modewort hat sich mehr als zwei Jahrzehnte gehalten!) besteht
darin, Code zu erzeugen, der auch unter fehlerhaften
Eingabeparametern weiterlaeuft und diesen Code dann in
moeglichst vielen anderen Projekten ohne grossen Aufwand
weiterverwenden zu koennen. Dieses Problem wird von der
strukturierten Programmierung ueberhaupt nicht angesprochen -
es war damals (ausserhalb gewisser akademischer Zirkel) auch
gar nicht existent.

Und so kommt es, dass die Lehre der strukturierten
Programmierung zwar sicherlich sehr nuetzlich ist, aber bei
weitem nicht vollstaendig und in einigen Punkten fuer den
praktichen Einsatz einfach unsinnig.

>Versuch mal in einem Programm mit mehreren break's in einer
>Schleife, das ein fremder geschrieben hat, nach 10 Jahren noch ein Statement
>unmittelbar vor dem Schleifenabbruch einzufuegen (z.B. das Ruecksetzen eines
>devices oder sowas).

Wenn Dir das hilft, dann will ich das gerne tun. Der folgende
Code ist mehr als 20 Jahre alt und stammt nicht von mir,
sondern von AT&T. Er ist Bestandteil von UNIX V7, das auf einer
PDP-11 laeuft. Ich habe ihn aus Gruenden der Uebersichtlichkeit
und aus Gruenden der Urheberrechts ein wenig verkuerzt.

Die Funktion exece() ist eine zentrale Funktion von UNIX. Sie
ist der einzige Weg, mit dem man neuen Code in das Image eines
Prozesses laden kann, d.h. sie tut in etwa das, was CHAIN in BASIC
macht: Sie laedt ein Programm nach und startet dieses.

exece() ist keine kurze Funktion: Sie ist knapp 130 Zeilen lang. Die
Kommentare sind von mir:

exece()
{
register nc;
register char *cp;
register struct buf *bp;
register struct execa *uap;
int na, ne, ns, bno, ucp, ap, c;
struct inode *ip;

/* Wenn der Name des auszufuehrenden Programms nicht
in eine Datei uebersetzbar ist: weg!
*/
if ((ip = namei(uchar, 0)) == NULL)
return;

/* Wenn auf die auszufuehrende Datei keine Zugriffsrechte
bestehen: weg!
*/
if(access(ip,IEXEC)
|| ((ip->i_mode&IFMT) != IFREG)
|| ((ip->i_mode&(IEXEC|(IEXEC>>3)|(IEXEC>>6))) == 0)) {
u.u_error = EACCES;
iput(ip);
return;
}

[ 8 Zeilen Initialisierung mit linearem Kontrollfluss geloescht ]
/* Wenn kein Speicher zum Start des Programmes zu bekommen
ist: System anhalten (das Aequivalent zu exit() im
Kernel).
*/
if ((bno = malloc(swapmap,(NCARGS+BSIZE-1)/BSIZE)) == 0)
panic("Out of swap");
[ ueber 100 Zeilen weiteren Code mit aehnlicher
Struktur geloescht ]

Das ist genau die Form Code, die ich weiter oben skizziert
habe. Sie ist gaengig, leicht zu lesen und leicht zu warten -
selbst nach mehr als 20 Jahren noch.

An anderen Stellen in V7 UNIX findest Du massenhaft das
goto-Konstrukt, dass ich oben angedeutet habe und das
schliesslich in den Nachfolgesprachen von C zu einem richtigen
Exception-Handler mutiert ist.

Genau solche Strukturen sind in ISO-PASCAL (im Gegensatz zu
Turbo-Pascal) aber kaum zu konstruieren. Zum einen musst Du
if's unnoetig verschachteln, weil keine short circuit
evaluation existiert:

if ( (zeiger) && (zeiger->komponente)) ...

ist kein gueltiges Pascal. Zum anderen ist das Konzept "ein
entry, ein exit" bei richtigen Funktionen einfach bloedsinnig.
Du glaubst doch nicht im ernst, dass der Code, den ich da oben
gezeigt habe, uebersichtlicher wird, wenn man statt

if (waechter)
{
something;
return errorcode;
}
if (another waechter)
{
something else;
return errorcode;
}

nutritional value;
return errorcode;

gezwungen wird

if (waechter) {
something;
} else {
if (another waechter) {
something else;
} else {
nutritional value;
}
}
return errorcode;

zu schreiben, nur um den single entry, single exit-Konzept
genuege zu tun? Und das nicht bei dem o.a. Spielzeug-Code,
sonern bei Produktions-Sourcen mit etwa einem halben bis einem
ganzen Dutzend solcher Waechter?

Kristian
--
Kristian Koehntopp, Wassilystrasse 30, 24113 Kiel, +49 431 688897
"Und das T ist Markenzeichen der Telekom... (klar, man erkennt es ja
sofort an tief heruntergezogenen Mundwinkeln des Querstrichs...)"
-- Rainer Zocholl in tp.forum

--- FIDOGATE 3.9.3
* Origin: Fido-Gateway @ white.schulung.netuse.de (2:240/2123.59)

Thomas Seeling

unread,
Jul 23, 1996, 3:00:00 AM7/23/96
to

Hallo, Herbert!

*** Am Montag 22. Juli 1996 um 00:27 schrieb Herbert Rosenau an Robert H.
Hanko:

HR> int fertig = FALSE;

HR> for (/*init*/; !fertig && (/*abbruchbedingung*/); /*Abschluß*/) {

Das bringt mich auf eine allgemeine Bemerkung:

es ist ziemlich unelegant, in einer Schleifenbedingung permanent boole'sche
Operatoren zu verwenden. Sie arbeiten zwar fix (wenig Takte), aber man sich das
leicht ersparen, sogar ohne Verlust an Lesbarkeit, wenn man in etwa:

int nichtfertig=TRUE; /* invertierter Startinhalt zu vorher */

for (init; nichtfertig && abbruch; inkrement) {
if (irgendwas) nichtfertig=FALSE;
}

Das erspart in diesem simplen Beispiel pro Schleifendurchlauf ein "not".


Tschau...Thomas

--- E3-32/1.11-32/2.50+
* Origin: Die TeX-Box +49-6034-930021 V.34 -930022 ISDN 24h (2:244/1130.42)

Rainer Huebenthal

unread,
Jul 24, 1996, 3:00:00 AM7/24/96
to

Bonjour Erhard,


RH>> Nope. Ich benutze GOTO zu genau einem Zweck: im Fehlerfall

RH>> Sprung zum Funktionsende. Das ist IMHO lesbarer als zig
RH>> if/case Konstrukte, die dann alle direkt vor dem return
RH>> terminieren.

ES> So, und wenn du dann an einer bestimmten Stelle zwischen
ES> deinem goto und dem Funktionsende noch was einfuegen musst,
ES> was auch im Fehlerfall zur Ausfuehrung kommen soll,

Da kann nichts zur Fehlerausfuehrung kommen. Ich meine harte
Fehler, mit denen die Funktion nichts mehr anfangen kann. zB
Database nicht vorhanden oder nicht zugaenglich. Was soll dann
eine Funktion noch tun, die dazu da ist, einen/mehere Selects
abzusetzen ? Es gibt in diesem Falle nicht anderes, als einen
Statuscode zu setzen und die Funktion zu verlassen. Was in einem
solchen Fall dann weiter zu tun ist, muss der Aufrufer
entscheiden, schliesslich hat er die Funktion "Daten lesen"
aufgerufen und muss nun sehen, wie damit fertig wird, dass er dir
Daten nicht bekommt. "Daten lesen" kann seine Aufgabe schlicht
und ergreifend nicht erfuellen, hat aber keine Entscheidung
darueber zu treffen, wies nun wieter geht oder ob etwas anderes
zu tun ist.

ES> kannst du deine ganze Implementierung ueber den Haufen
ES> schmeissen.

Nein.

ES> denen viel leichter, als wenn du mit goto's kaempfen musst,
ES> die du nach x Jahren sehr wahrscheinlich gar nicht mehr alle
ES> findest.

Ich habe es mit GOTO's wesentlich leichter, die nur zu einem
einzigen Zweck da sind: Naemlich tief verschachtelte IF/Case
Konstrukte zu vermeiden. Wenn es keinen Sinn mehr macht, in
dieser Funktion zu verbleiben, dann verlasse ich sie. Und zwar
ueber _einen_ Punkt und nicht ueber n Returns (wie vielleicht
jetzt der eine oder andere einwenden moechte :-) ). Mehrere
Returns in einer Funktion sind naemlich allerschlechtester
Programmierstil. Ich erreiche mit meinem Goto naemlich genau den
_einen_ Ausgang, den eine Funktion haben sollte. Und ist noch
Aufraeumarbeit zu leisten, so steht das zwischen goto und return.
Und wird damit immer aufgerufen. Fuer mich fuehrt das zwanghafte
vermeiden von gotos zu unleserlichen Programmen.


au revoir
Rainer


--- CrossPoint v3.11 R
* Origin: Noctambule lunatique qui clignote dans le soir (2:2435/610.21)

Erhard Schwenk

unread,
Jul 24, 1996, 3:00:00 AM7/24/96
to

Hallo Soenke!


SM> Wozu sich diese erzieherischen Pascal-Thesen aufladen?
SM> Die Anweisungen break, continue und return (inmitten der Funktion) sind
SM> eigentlich nichts anderes, als versteckte goto's, da sie den Block auf
SM> "unnatuerlichem" Wege verlassen. In C++ heissen die neuen goto's
SM> "Exceptions". ;)

Also, erstens mal sind das keine Pascal-Themen, sondern Programmierthemen, die
von der Sprache recht unabhaengig sind. Die Tatsache, dass bestimmte Dinge in
einer Sprache (C ist hier ein typisches Beispiel) zulaessig sind, heisst noch
lange nicht, dass sie auch sinnvoll oder sauber sind. Exceptions kannst du auch
nur bedingt mit break- oder goto-Konstruktionen vergleichen, da ihnen ein
voellig anderes Konzept zugrunde liegt. Ausserdem ist das Arbeiten mit
Exceptions ebenso wie das Arbeiten mit goto tatsaechlich sehr gefaehrlich, wenn
man nicht gaanz vorsichtig programmiert.

SM> Willst Du ein Programm fertigstellen, oder willst Du fuer deine Sourcen
SM> Schoenheitspreise gewinnen?

Ich will Sourcen erstellen, die man auch in 10 Jahren noch warten kann, ohne
dabei gefahr zu laufen, durch ein uebersehenes goto vor den eingefuegten
Anweisungen tagelang zu debuggen.

SM> In vielen Faellen ist der Aufwand einfach nicht gerechtfertigt, ein goto
SM> durch einen anderen Konstrukt zu ersetzen.

Es ist laengst nachgewiesen, dass der Aufwand nur ein scheinbarer ist. Und der
Aufwand, die goto's beim Warten des Programms nachher zu suchen und evtl. dann
die ganze "goto-Struktur" wieder umschmeissen zu muessen bzw. der Aufwand, der
durch mit diesen Konstrukten provozierte Wartungsfehler entsteht, ist um ein
vielfaches hoeher. Ich kann dir gerne mal so eine Source mit massenhaft breaks
zur Verfuegung stellen. Wenn so ein goto von ner mehrfach Verschachtelten
Schleife ans Funktionsende springt (und das an mehreren Stellen), und du musst
evtl. 3 Verschachtelungsebenen weiter aussen noch ne Anweisung einbauen, dann
hast du damit ein riesen Problem. Und wie gesagt: Bei einem sauber erstellten
Design sind solche Konstruktionen schon Konstruktionsbedingt ausgeschlossen,
d.H. du kannst gar nicht auf die Idee kommen, sie zu verwenden.

Kristian Köhntopp

unread,
Jul 24, 1996, 3:00:00 AM7/24/96
to

Erhard_...@p65.f3001.n2487.z2.fidonet.org (Erhard Schwenk) writes:
>> [ SEH Beispiel geloescht ]

>Das macht man erstens mal viel eleganter ueber ein paar Praeprozessor-Makros.

*Elegant* macht man das mit einer Spracherweiterung: Structured
Exception Handling (SEH). So zu finden in C++, Objective-C,
Java und einigen Microsoft-Erweiterungen von C.

Erhard Schwenk

unread,
Jul 25, 1996, 3:00:00 AM7/25/96
to

Hallo Rainer!


RH> Da kann nichts zur Fehlerausfuehrung kommen. Ich meine harte
RH> Fehler, mit denen die Funktion nichts mehr anfangen kann. zB
RH> Database nicht vorhanden oder nicht zugaenglich. Was soll dann
RH> eine Funktion noch tun, die dazu da ist, einen/mehere Selects
RH> abzusetzen ?

Zum Beispiel die zwei anderen Datenbanken, die sie zuvor geoeffnet hat, wieder
sauber schliessen (aber nur, wenn sie geoeffnet wurden!) oder das Filesystem
flushen.

RH> Es gibt in diesem Falle nicht anderes, als einen
RH> Statuscode zu setzen und die Funktion zu verlassen. Was in einem solchen
RH> Fall dann weiter zu tun ist, muss der Aufrufer entscheiden, schliesslich
RH> hat er die Funktion "Daten lesen" aufgerufen und muss nun sehen, wie
RH> damit fertig wird, dass er dir Daten nicht bekommt. "Daten lesen" kann
RH> seine Aufgabe schlicht und ergreifend nicht erfuellen, hat aber keine
RH> Entscheidung darueber zu treffen, wies nun wieter geht oder ob etwas
RH> anderes zu tun ist.

RH> Fuer mich fuehrt das zwanghafte vermeiden von gotos zu
RH> unleserlichen Programmen.

Es ist eben _nicht_ zwanghaft. Obiges Beispiel:

Nach 10 Jahren soll das Prg dahingehend geaendert werden, dass deine Funktion
diese Daten aus zwei DB's zusammensuchen muss. Wenn die neue DB vor der bereits
implementierten geoeffnet werden soll, muss sie im Falle eines Fehlers beim
Oeffnen der alten wieder sauber zugemacht werden. Bereits da kommt deine
Konstruktion ins Schwimmen. UNd sowas kann nun wirklich Aufwand erzeugen. Und
wie bereits erlaeutert: Mit ner ordentlichen Design-Methode kannst du gar nicht
auf goto's kommen. Und ich will doch wohl hoffen, dass du deine Programme auf
Analyse und Design aufbaust und dieses Design dann auch implementierst, sonst
hat die ganze Diskussion natuerlich keinen Sinn, denn dann produzierst du eh
potentiellen Spaghetti-Code. Das selbe Ergebnis gibts z.B. auch, wenn mehrere
Speicherbloecke alloziert werden und einer davon nicht mehr zu kriegen ist oder
bei anderen Betriebsmitteln. Vielleicht zur Verdeutlichung ein Code-Beispiel:

Deine Variante:

while (Bedingung1)
{
int xyz;

...

if (xyz == 3) DBOeffnen(ZusatzDB);

while (Bedingung2)
{


switch (gewaehlte_datenbank)
{
case KUNDEN:
...
if (OeffneKunDB == FEHLER) goto fehler;
break;

case LIEFERANTEN:
if (OeffneLieDB == FEHLER) goto fehler;
break;

case ARTIKEL:
if (OeffneArtDB == FEHLER) goto fehler;
break;
}
}
}

...

fehler:
return FEHLER;


So, nun folgendes Wartungsproblem:

-im Fehlerfall muss die ZusatzDB geschlossen werden, falls sie vorher
geoeffnet wurde, und zwar in der aeusseren Schleife
(wo sie auch geoeffnet wurde)

Natuerlich gibts dafuer ne Masse Loesungen, aber die strukturell sauberste ist
eben die Entfernung der goto's. Diese Form von Goto's war vielleicht zu
COBOL-Zeiten noch wichtig, aber in C oder Pascal sollte man sowas wirklich
tunlichst unterlassen. Steht uebrigens auch in vielen mir bekannten
Code-Richtlinien, die nicht alle ausschliesslich von der Uni stammen, sondern
auch teilweise aus Industriebetrieben. Und es hat sich auch bewaehrt.

Thomas Seeling

unread,
Jul 25, 1996, 3:00:00 AM7/25/96
to

Hallo, Rainer!

*** Am Mittwoch 24. Juli 1996 um 00:00 schrieb Rainer Huebenthal an Erhard
Schwenk:


RH>>> Nope. Ich benutze GOTO zu genau einem Zweck: im Fehlerfall
RH>>> Sprung zum Funktionsende. Das ist IMHO lesbarer als zig
RH>>> if/case Konstrukte, die dann alle direkt vor dem return
RH>>> terminieren.

Dijkstra und Wirth haben mittlerweile auch festgestellt, dass GOTO
in bestimmten Situationen brauchbar ist.

Der Artikel von Dijkstra ("Goto considered harmful") besteht im
wesentlichen darin, dass der Sprung mitten _in_ einen Block
verdammt wird, also etwa

i=175;
goto hallo;

for (i=32; i<127; ++i) {
hallo:
printf("%c ",i);

Torsten Landschoff

unread,
Jul 26, 1996, 3:00:00 AM7/26/96
to

Hallo Rainer,

>Addresse: Rainer_H...@p21.f610.n2435.z2.fido.de

Sagt mal, spinn ich, oder lesen wir hier jetzt Fidomails über ein Internetgate?

cu
Torsten

Soenke Mueller-Lund

unread,
Jul 26, 1996, 3:00:00 AM7/26/96
to

Moin Erhard,

SM>> Wozu sich diese erzieherischen Pascal-Thesen aufladen?
SM>> Die Anweisungen break, continue und return (inmitten der Funktion) sind
SM>> eigentlich nichts anderes, als versteckte goto's, da sie den Block auf
SM>> "unnatuerlichem" Wege verlassen. In C++ heissen die neuen goto's
SM>> "Exceptions". ;)

> Also, erstens mal sind das keine Pascal-Themen,

ich schrieb "Thesen"!

SM>> Willst Du ein Programm fertigstellen, oder willst Du fuer deine Sourcen
SM>> Schoenheitspreise gewinnen?

> Ich will Sourcen erstellen, die man auch in 10 Jahren noch warten kann, ohne
> dabei gefahr zu laufen, durch ein uebersehenes goto vor den eingefuegten
> Anweisungen tagelang zu debuggen.

Wie ich bereits erwähnte (hast Du aber nicht mitgequotet), habe ich selbst
"goto" höchstens zweimal eingesetzt. Mir ging es eher um die Verwendung
von "break" und "continue".

SM>> In vielen Faellen ist der Aufwand einfach nicht gerechtfertigt, ein goto
SM>> durch einen anderen Konstrukt zu ersetzen.

> Es ist laengst nachgewiesen, dass der Aufwand nur ein scheinbarer ist.

Sorry, diesen "Nachweis" stelle ich hiermit in Frage.

> Und der Aufwand, die goto's beim Warten des Programms nachher zu suchen
> und evtl. dann die ganze "goto-Struktur" wieder umschmeissen zu muessen

> bzw. der Aufwand, ...

Halt mal an!
Niemand von den "goto-Befürwortern" hier im Netz hat vor, sämtliche
Kontrollstrukturen durch goto's zu ersetzen. Es geht hier nur um den
Einsatz einer einzigen wohlplazierten "goto"-Anweisung, um z.B. eine
tiefverschachtelte Schleife zu verlassen.

Ich programmiere nicht erst seit gestern, aber ich weiß nicht, wie

> der durch mit diesen Konstrukten provozierte Wartungsfehler
> entsteht, ist um ein vielfaches hoeher.

beim Einsatz _eines_ goto's Wartungsfehler entstehen können.

> Ich kann dir gerne mal so eine Source mit massenhaft breaks zur
> Verfuegung stellen.

Spar dir das bitte. Niemand will auch "massenhaft" break's einsetzen.

> Und wie gesagt: Bei einem sauber erstellten Design sind solche
Konstruktionen schon
> Konstruktionsbedingt ausgeschlossen, d.H. du kannst gar nicht auf die
> Idee kommen, sie zu verwenden.

Meinetwegen.

Ciao
Sönke

Siegmund Schreiber

unread,
Jul 26, 1996, 3:00:00 AM7/26/96
to

Thomas Seeling schrieb am 7-23-96, 23:11 in C:

HR> int fertig = FALSE;
TS>

HR> for (/*init*/; !fertig && (/*abbruchbedingung*/); /*Abschluß*/) {
TS>
TS>Das bringt mich auf eine allgemeine Bemerkung:
TS>
TS>es ist ziemlich unelegant, in einer Schleifenbedingung permanent
TS>boole'sche Operatoren zu verwenden. Sie arbeiten zwar fix (wenig
TS>Takte), aber man sich das leicht ersparen, sogar ohne Verlust an
TS>Lesbarkeit, wenn man in etwa:
...

Ich frage mich allerdings, ob ein guter Compiler dieses NOT nicht gleich in die
Abbruchbedingung integriert. Schließlich haben die meisten Prozessoren doch
passende Jxx-Befehle. Und den Compare-Befehl kann man ohnehin nicht einsparen.

Siegmund

Erhard Schwenk

unread,
Jul 26, 1996, 3:00:00 AM7/26/96
to

Hallo Thomas!


TS> int nichtfertig=TRUE; /* invertierter Startinhalt zu vorher */

TS> for (init; nichtfertig && abbruch; inkrement) {
TS> if (irgendwas) nichtfertig=FALSE;
TS> }

TS> Das erspart in diesem simplen Beispiel pro Schleifendurchlauf ein "not".

Ist einerseits richtig, andererseits entspricht die umgekehrte Variante aber
mehr der menschlichen Denkweise und erscheint zumindest mir dadurch
verstaendlicher. Und das "not" ist in den meisten Programmen eigentlich
sch...egal, denn Rechenzeit-kritisch ist auf den heutigen Rechnern eh fast
nichts mehr.

Rainer Huebenthal

unread,
Jul 26, 1996, 3:00:00 AM7/26/96
to

Bonjour Thomas,

TS> im wesentlichen darin, dass der Sprung mitten _in_ einen
TS> Block verdammt wird, also etwa
TS>
TS> i=175;
TS> goto hallo;
TS>
TS> for (i=32; i<127; ++i) {
TS> hallo:
TS> printf("%c ",i);
TS> }
TS>

Wenn mir jemand solchen Code vorlegt, war er die laengste Zeit in
meinem Projektteam. Wer sowas macht, kann evtl Tokens so
anordnen, dass der Compiler nicht mehr mosert, aber programmieren
kann man das ja nicht mehr nennen.

Herbert Rosenau

unread,
Jul 26, 1996, 3:00:00 AM7/26/96
to

Hi Thomas,

am 23.07.96 23:11 erzähltest Du Herbert

HR>> int fertig = FALSE;

HR>> for (/*init*/; !fertig && (/*abbruchbedingung*/); /*Abschluß*/) {

TS> Das bringt mich auf eine allgemeine Bemerkung:

TS> es ist ziemlich unelegant, in einer Schleifenbedingung permanent
TS> boole'sche Operatoren zu verwenden. Sie arbeiten zwar fix (wenig
TS> Takte), aber man sich das leicht ersparen, sogar ohne Verlust an
TS> Lesbarkeit, wenn man in etwa:

Das kommt letztenlich auf einige Faktoren an. In dem kurzen beispiel ist das
auch nur vereinfacht ausgedrückt. Erweitert man das ganze zu 'solange kein
Fehler (ferig ist 0)' und Fehlerzustände durch einen Wert != 0 kennzeichnet,
kann man gleichartige Bearbeitungen nach der Schleife sehr wohl wiederum
zusammenfassen - und wenn es nur die Ausgabe einer Fehlermeldung ist.

Man muß wissen, daß 0 == FALSE und != 0 (also alles Mögliche eben TRUE ist.
Wenn der eigentliche Abbruchgrund wiederum eine eigene Verarbeitung hat, kommt
man um den '!-Operator nicht herum, es sei denn man zieht Langschrift vor.

Erhard Schwenk

unread,
Jul 26, 1996, 3:00:00 AM7/26/96
to

Hallo Kristian!


K> Genaugenommen ist es total schnurz, ob Dein Programm
K> strukturiert ist - das Designziel, das erreicht werden soll ist
K> nicht "Struktur des Quelltextes", sondern "Leichte Wartbarkeit"
K> und "Uebersichtlichkeit". Die Struktur ist dabei nur ein Mittel
K> zur Erreichung dieses Zweckes, aber keine hl. Lehre. Das
K> verlieren die Verfechter von reinem ISO-Pascal manchmal aus den
K> Augen.

Wenn du dich streng an "ISO-Pascal" wie du es nennst haelst, ist es durchaus
moeglich, Wartbarkeit und Struktur zu erreichen. Die Frage ist, wie du deine
Programme entwickelst. Wenn du ordentliche Analyse- und Design-Methoden (ich
weiss, das wiederholt sich) nimmst, _kannst_ du gar kein goto einbauen.

K> Und unter diesem Kritierium schneidet Pascal dann gelegentlich
K> nicht besonders gut ab. Wie Kernighan demonstriert, fuehrt die
K> Armut an solchen verkuerzenden Kontrollstrukturelementen wie
K> "break" dazu, dass Programmierer aus Bequemlichkeit auf die
K> korrekte, langatmige Formulierung des Codes verzichten.
K> Stattdessen schreiben sie die verkuerzte, aber leider unter der
K> Auswertungsreihenfolge von ISO-Pascal *falsche* Form hin.

K> Das ist ja dann auch genau der Grund, warum man in Turbo-Pascal
K> Dinge wie short circuit evaluation, Schleifenabbrueche und so
K> weiter als Sprachelemente eingefuehrt hat: Damit aus einer
K> Wandtafelsprache eines Algorithmenprofessors ein Werkzeug wird,
K> das im taeglichen Gebrauch ueberleben kann.

Diese scheinbaren Verkuerzungen erzeugen nicht nur nach meiner Erfahrung in
Wahrheit nur Verlaengerungen bei den Wartungsarbeiten. Sie wurden auch nicht
eingefuehrt, weil sie notwendig sind, sondern weil einige goto-verliebte BASIC-
und C-Programmierer nicht in der Lage waren, den Gedanken der strukturierten
Programmierung richtig zu verstehen und umzusetzen. Schleifenabbrueche sind in
groesseren Programmen ne absolute Sauerei, und wenn du jemals 200 kb Quellcode
warten musstest, der damit durchsetzt war, dann weisst du auch warum.

K> sind gaengige Redewendungen in C und das seit Jahrzehnten.
K> Programmcode dieser Form zieht sich zum Beispiel durch von den
K> Quellen fuer den UNIX V7 Kernel und die dazugehoerenden
K> Utilities bis hin zu aktuellen Versionen von 4.4BSD und Linux.
K> Und das, obwohl sich der Programmierstil ansonsten ziemlich
K> radikal gewandelt hat (das ist eine andere, nicht minder
K> interessante Geschichte).

Erstens sind diese Konstruktionen uralt, zweitens haben sie mit Struktur nichts
zu tun und drittens sind genau das die Konstruktionen, die heute eine Wartung
z.B. alter COBOL-Software nahezu unmoeglich und deshalb eine Neuentwicklung
vieler Softwarepakete noetig machen. Genau das ist auch der Grund, warum die
strukturierte Programmierung nicht zum gewuenschten Erfolg wiederverwendbaren
Codes fuehrte: weil sich zuviele Leute eben nicht an die Strukturierungen
halten koennen. Und (im Gegensatz zur Meinung vieler Pascal-Freaks) Struktur
findet zunaechst mal im Kopf des Entwicklers statt, nicht in der Sprache.

K> Solche Redewendungen sind ausserdem auch sehr uebersichtlich,
K> weil sie naemlich die Fehler- und Abbruchbedingungen, auf die
K> getestet wird, in einer leicht zu lesenden und auch raeumlich
K> zusammengehoerenden Form aufschreiben.

Sie sind strukturmaessiger Datenmuell, weil sie unerwartete
Programmverzweigungen erzeugen, die in groesseren Quelltexten nur sehr schwer
zu ueberblicken sind. Wenn du bei der Wartung so ein goto oder break oder
continue uebersiehst, rennst du dem tagelang hinterher.

K> Wenn das nicht in die Ideologie der sogenannten strukturierten
K> Programmierung passt, dann ist das ein Grund, ueber die
K> Leistungsfaehigkeit dieser Ideologie nachzudenken.

Es ist eher ein Anlass, ueber dein Verstaendnis von Struktur nachzudenken.
Strukturierte Programmierung heisst, mit moeglichst wenigen
Grundkonstruktionen, die noch dazu einfach zu verstehen sind, alle gegebenen
Probleme loesen. Das ist ein Paradigma, das sich absolut bewaehrt hat, und wenn
du wirklich ernsthaft Software entwickelst und entsprechende Methoden
verwendest, kannst du aus diesen Strukturen schon rein methodisch auch gar
nicht mehr ausbrechen. Diese Tatsachen aendern aber nichts an der
Leistungsfaehigkeit der "Ideologie" strukturierte Programmierung.

K> Auch das ist
K> getan worden. Das Resultat ist zum Beispiel das formalisierte
K> Exception-Handling in Objective-C, C++, Java oder den
K> Microsoft-C-Erweiterungen (siehe Jeffrey Richter, "Advanced
K> Windows", Microsoft Press, Kapitel 14, "Structured Exception
K> Handling").

Die OOD-maessig hoechst umstritten ist und Quellcodes bereits heute schwer
wartbar werden liess. Bis heute ist umstritten, ob Exceptions nun
strukturmaessig sinnvoll oder gefaehrlich sind. Und nach dem, was ich bisher
sah, welche Exceptions von manchen Leuten verbrochen werden, halte ich sie eher
fuer verboten.

K> Das dem so ist, ist nicht verwunderlich. "Strukturierte
K> Programmierung" ist ein Konzept aus den Zeiten von BASIC, COBOL
K> und FORTRAN (man sehe sich an, von welchem Datum "GOTO's
K> considered harmful" ist). Damals war das Hauptproblem, Code so
K> ans Rennen zu bekommen, dass er ueberhaupt Leistung brachte.
K> Dieses Problem wurde von den Informatik-Schlipstraegern damals
K> als "die Softwarekrise" bezeichnet.

Die Softwarekrise war wohl etwas mehr als ein Performance-Problem. (wenn sie
ueberhaupt existierte). Aber auch die OO stammt aus den spaeten 60er Jahren,
sie ist nur wenige Jahre aelter als die Strukturierte Programmierung. Das
Problem war auch nicht, Programme am Laufen zu halten, sondern die zunehmende
Komplexitaet der Softwarepakete in den Griff zu bekommen.

K> Heute hat man mit der Erzeugung von laufendem Code und dem
K> Verstaendnis von grundlegenden Kontroll- und Datenstrukturen
K> keine Probleme mehr. Die heutige "Softwarekrise" (ja, dieses
K> Modewort hat sich mehr als zwei Jahrzehnte gehalten!) besteht
K> darin, Code zu erzeugen, der auch unter fehlerhaften
K> Eingabeparametern weiterlaeuft und diesen Code dann in
K> moeglichst vielen anderen Projekten ohne grossen Aufwand
K> weiterverwenden zu koennen. Dieses Problem wird von der
K> strukturierten Programmierung ueberhaupt nicht angesprochen -
K> es war damals (ausserhalb gewisser akademischer Zirkel) auch
K> gar nicht existent.

Also, die wiederverwendbarkeit von Code wird in der strukturierten
Programmierung sehr wohl angesprochen, z.B. im Rahmen sauberer Designtechniken
mit Modularisierung. Und ob das Problem wirklich akademisch ist, laesst sich
daran erkennen, wieviel Zeit fuer unstrukturierte COBOL- und BASIC-Programme
auch heute noch aufgewendet werden muss und wie teuer es ist, diese Anwendungen
heute neu zu entwickeln. Wenn bei deren Codierung bereits sauber designt und
strukturiert worden waere, waere dieser Aufwand heute wesentlich kleiner. Aber
wer machte sich damals schon die Muehe, DFD's und NSD's detailliert zu
entwerfen, zumal es an entsprechenden TOols mangelte?

K> Und so kommt es, dass die Lehre der strukturierten
K> Programmierung zwar sicherlich sehr nuetzlich ist, aber bei
K> weitem nicht vollstaendig und in einigen Punkten fuer den
K> praktichen Einsatz einfach unsinnig.

Sie ist nicht nur vollstaendig, sondern auch sinnvoll. Es ist nachgewiesen,
dass jedes mit "goto" und "unstrukturierten" Mitteln loesbare Problem auch eine
strukturierte Loesung hat, darueber gibts auch ne Doktorarbeit.

K> ist kein gueltiges Pascal. Zum anderen ist das Konzept "ein
K> entry, ein exit" bei richtigen Funktionen einfach bloedsinnig.

Im Gegenteil, alles andere ist unuebersichtlich und Muell. Ich weiss nicht, wo
du programmierst, aber solcher Code wuerde bei mir in der Firma direkt in der
Tonne landen. Gottseidank.

K> zu schreiben, nur um den single entry, single exit-Konzept

K> genuege zu tun? Und das nicht bei dem o.a. Spielzeug-Code,
K> sonern bei Produktions-Sourcen mit etwa einem halben bis einem
K> ganzen Dutzend solcher Waechter?

Das ist absolut nicht komplexer, kostet kaum Rechenzeit und spart bei der
Wartung extrem Entwicklungszeit ab. Uebrigens: Auch "Produktions-Sourcen" z.B.
kaufmaennischer C/S-Datenbankanwendungen werden zumindest in meiner Firma nach
Moeglichkeit mit handlichen Funktionen strukturiert, die entweder nur eine
Strukturkomponente oder nicht mehr als etwa 50-100 Zeilen Quellcode umfassen
duerfen. Alles andere waere auch schon wieder ein Designfehler.

ps: Mit deinem Absender scheint was nicht zu stimmen.

Erhard Schwenk

unread,
Jul 27, 1996, 3:00:00 AM7/27/96
to

Hallo Kristian!

K> *Elegant* macht man das mit einer Spracherweiterung: Structured
K> Exception Handling (SEH). So zu finden in C++, Objective-C,
K> Java und einigen Microsoft-Erweiterungen von C.

Ist aber wartungsmaessig u.U. auch ganz nett problematisch und ausserdem nicht
mehr C, sondern ne auf C aufbauende Sprache. Aber prinzipiell gilt auch hier:
Wenn du ne ordentliche Analsye und ein korrektes (und verifiziertes) Design
machst, fallen solche Konstrukte schon von Vorne herein raus, ohne dass es dir
ueberhaupt bewusst wird. Und wenn du sie nachher wieder einbaust, hast du ne
Todsuende begangen und was anderes Programmiert, als du designt hast.

Erhard Schwenk

unread,
Jul 27, 1996, 3:00:00 AM7/27/96
to

Hallo Markus!

MM> Vorschlag: ein break; + Setzen eines Abbruchflags in der inneren und eine
MM> Abfrage dieses Abbruchflags in der aeusseren Schleife.

MM> Oder ein goto. :-) Tu Dir da nur keinen Zwang an. ;-)

Beides mieser Stil und _verboten_ fuer einen ordentlichen Programmierer (und
bei sauberer Entwicklung mittels A- und D-Tools auch gar nicht machbar).

Erhard Schwenk

unread,
Jul 27, 1996, 3:00:00 AM7/27/96
to

Hallo Markus!

MM> Hi Rainer,

MM> 20 Jul 96 00:00, Rainer Huebenthal wrote to Erhard Schwenk:

MM> [...]
RH>> Nope. Ich benutze GOTO zu genau einem Zweck: im Fehlerfall Sprung zum
RH>> Funktionsende. Das ist IMHO lesbarer als zig if/case Konstrukte, die dann
RH>> alle direkt vor dem return terminieren.

MM> Auch das kann man u. U. geschickt (oder krampfhaft ;-) ) umgehen:

MM> Was man nicht alles tut, um nicht dieses verpoente "goto" zu benutzen. :-)

Was du machst, ist strukturiert betrachtet auch nicht besser. Dadurch, dass du
goto durch ein anderes Wort (hier break) ersetzt, ist der strukturfehler noch
lange nicht behoben. Der Code hat genau die gleichen Probs wie ein mit goto's
gesetzter Code. Bessere Variante siehe andere Mail von gestern. Es geht nicht
darum, das Wort "goto" zu vermeiden, sondern die Struktur "Sprung" bzw.
"Unbedingter Sprung" nicht zu verwenden. Beides ist eigentlich schon Aufgabe
der Design-Phase.

Erhard Schwenk

unread,
Jul 27, 1996, 3:00:00 AM7/27/96
to

Hallo Jan-Erik!

JR> Moin Erhard!

RH>>> Nope. Ich benutze GOTO zu genau einem Zweck: im Fehlerfall Sprung zum
RH>>> Funktionsende. Das ist IMHO lesbarer als zig if/case Konstrukte, die

RH>>> dann alle direkt vor dem return terminieren.

JR> ich habe dieses schema via konsequenter labelelierung in c uebernommen,
JR> wenn es wirklich nicht vernuenftig ohne gotos geht. und _das_ ist
JR> definitiv auch wartbar.

Es geht immer definitiv vernuenftig ohne gotos. Nimm ne richtige Design-Methode
(wenns nicht grad OO sein muss, z.B. SADT oder so was in der Richtung) und du
hast das Problem nicht. Und gleichzeitig hast du schon mit der Analyse und dem
Design die halbe Doku fuer deinen Code geschrieben, musst nur noch ein
Funktions- und Variablenverzeichnis anhaengen (vorausgesetzt, es existiert ein
Pflichtenheft).

Rainer Huebenthal

unread,
Jul 27, 1996, 3:00:00 AM7/27/96
to

Bonjour Erhard,

ES> Zum Beispiel die zwei anderen Datenbanken, die sie zuvor
ES> geoeffnet hat, wieder sauber schliessen (aber nur, wenn sie
ES> geoeffnet wurden!) oder das Filesystem flushen.

Zwischen FuncExit (dieses Label heisst in allen meinen Funktionen
so) und dem return muss man natuerlich noch alles wieder
aufraeumen, was man so zur Initialisierung braucht. Es ist
schliesslich ziemlich uebel, am Anfang der Funktion Speicher
anzufordern, dann zu merken, dass es nicht weitergeht und
rauszuspringen, ohne diesen Speicher wieder freizugeben. Sowas
steht zB bei mir zwischen FuncExit und return.

ES> Nach 10 Jahren soll das Prg dahingehend geaendert werden,
ES> dass deine Funktion diese Daten aus zwei DB's zusammensuchen
ES> muss. Wenn die neue DB vor der bereits implementierten
ES> geoeffnet werden soll, muss sie im Falle eines Fehlers beim
ES> Oeffnen der alten wieder sauber zugemacht werden. Bereits da
ES> kommt deine Konstruktion ins Schwimmen.

nope. Eine Funktion hat nicht darueber zu entscheiden, ob die
Datenbank geoeffnet bleiben muss oder sie zu schliessen hat. Wo
bleibt deine Beschraenkung auf 50 LOC pro Funktion. Es eben eine
Funktion, die die Datenbank oeffnet, und es gibt eine(mehrere),
die sie liest, und es gibt eine, die sie schliesst. Diejenige,
welche sie liest, hat nicht darueber zu entscheiden, ob die
Datenbank geschlossen werden soll.

ES> wirklich Aufwand erzeugen. Und wie bereits erlaeutert: Mit
ES> ner ordentlichen Design-Methode kannst du gar nicht auf
ES> goto's kommen. Und ich will doch wohl hoffen, dass du deine
ES> Programme auf Analyse und Design aufbaust

Nein, ich baue meine Programme auf 3 der 4 CASE Phasen auf :
Planning, Analyse und Design. Construction lasse ich weg, da es
noch keine brauchbaren Code-generatoren gibt. Das was da
rauskommt ist Muell und muss manuell nachgebessert werden, da
kann ich es auch gleich weglassen.

ES> case ARTIKEL:
ES> if (OeffneArtDB == FEHLER) goto fehler;
ES> break;
ES> }
ES> }
ES> }
ES>
ES> ...
ES>
ES> fehler:

und hier kann man noch den Speicher freigeben (sofern er
erfolgreich alloziert wurde). Vorteil : Die exit Bedingung steht
einmal in der funktion und wird von jedem goto aus erreicht. Das
setzt natuerlich vorraus, dass die Speicherallozierung eine
strenge Bindung an die Funktion besitzt. Bei einer schwachen
Bindung gehoert das wieder in extra Funktionen.

ES> -im Fehlerfall muss die ZusatzDB geschlossen werden, falls
ES> sie vorher geoeffnet wurde, und zwar in der aeusseren
ES> Schleife (wo sie auch geoeffnet wurde)

Tritt waehrend des Lesens ein Fehler auf, so hat diese Routine
nicht darueber zu entscheiden, ob die DB geschlossenwerden muss.
Sie hat den Lesefehler "nach oben" weiterzureichen, sonst nichts.

ES> Natuerlich gibts dafuer ne Masse Loesungen, aber die
ES> strukturell sauberste ist eben die Entfernung der goto's.

Da koennen wir in 10 Jahren noch drueber streiten.

ES> tunlichst unterlassen. Steht uebrigens auch in vielen mir
ES> bekannten Code-Richtlinien,

Es steht im uebrigen auch in vielen mir bekannten Code-
Richtlinien, dass _ein_ goto an _das Ende_ der Funktion erlaubt
ist. Unter anderem in unserer Code-Richtlinie :-)

ES> von der Uni stammen, sondern auch teilweise aus
ES> Industriebetrieben. Und es hat sich auch bewaehrt.

Jou, es hat sich bewaehrt, das goto.

Uwe Moosheimer

unread,
Jul 28, 1996, 3:00:00 AM7/28/96
to

Hallo Herbert,

HR> Man muss wissen, dass 0 == FALSE und != 0 (also alles
HR> Moegliche eben TRUE ist. Wenn der eigentliche Abbruchgrund
HR> wiederum eine eigene Verarbeitung hat, kommt man um den
HR> '!-Operator nicht herum, es sei denn man zieht Langschrift
HR> vor.
Moment. Heisst das nicht so:
#define TRUE 1==1
#define FALSE !TRUE
????
Das ist dann aber ein grosser Unterschied ... :-)

Gruss Uwe

---
* Origin: Double - Box ... man goennt sich ja sonst nichts (2:246/1116)

Olaf Gerike

unread,
Jul 29, 1996, 3:00:00 AM7/29/96
to

Hallo Erhard,

>Deine Variante:
>
>while (Bedingung1)
> {
>[...]
> case KUNDEN:


> if (OeffneKunDB == FEHLER) goto fehler;
> break;

>[...]


> }
>
>...
>
>fehler:
> return FEHLER;
>
>
>So, nun folgendes Wartungsproblem:

Wie würdest Du das Problem denn lösen? Oder allgemein, wie beendest Du
verschachtelte Schleifen?

tschüß, Olaf

Thomas Seeling

unread,
Jul 29, 1996, 3:00:00 AM7/29/96
to

Hallo, Uwe!

*** Am Sonntag 28. Juli 1996 um 12:54 schrieb Uwe Moosheimer an Herbert
Rosenau:

UM> Moment. Heisst das nicht so:
UM> #define TRUE 1==1
UM> #define FALSE !TRUE
UM> ????

Du solltest um Definitionen aus mehreren Token immer Klammern setzen.

#define TRUE (1==1)

#define hallo(x,y) ( (x) < (y) ? (x) : (y) )

Erhard Schwenk

unread,
Jul 31, 1996, 3:00:00 AM7/31/96
to

Hallo Rainer!

RH> Einspruch. Sehr wohl machbar.

Dann hast du schlechte Tools. Oder du programmierst was anderes, als in deinem
Design steht.

Matthias Thiele

unread,
Aug 1, 1996, 3:00:00 AM8/1/96
to

Hallo Thomas

HR>> int fertig = FALSE;

HR>> for (/*init*/; !fertig && (/*abbruchbedingung*/); /*Abschluss*/) {

TS> Das bringt mich auf eine allgemeine Bemerkung:
TS>
TS> es ist ziemlich unelegant, in einer Schleifenbedingung permanent

TS> boole'sche Operatoren zu verwenden. Sie arbeiten zwar fix (wenig Takte),
TS> aber man sich das leicht ersparen, sogar ohne Verlust an Lesbarkeit, wenn
TS> man in etwa:

Das ist ein gutes Beispiel fuer eine ueberfluessige (manuelle)
Optimierung. Sowas kann ein richtiger Compiler heutzutage selber.
Ironischerweise erzeugt BC++ 4.5 fuer die Variante while (i) sogar mehr
Code als fuer die Variante while (!i). Allerdings kommt es bei beiden zu
gleichen Ausfuehrungszeiten (wenn man die Codegroesse und auswirkungen auf
den Cache vernachlaessigt).

Fuer den Fall while (!i && j) bzw while (i && j) wird, abgesehen von ein
JE statt JNE, identischer Code erzeugt. Ich denke, dass dieses Beispiel
auf alle modernen Compiler uebertragbar ist.

Vor 15 Jahren haette das Argument vielleicht gezogen, heute wuerde ich in
diesem Fall sagen: es ist ziemlich unelegant in einer Schleifenbedingung
extra alles umzudrehen nur um den Compiler die Optimierung einer Negation
zu ersparen :-).

und tschuess ...

Matthias (Thiele Moenchengladbach)


--- CrossPoint v3.1 R
* Origin: We apologize for the inconvenience. (2:2433/445.21)

Markus Mattes

unread,
Aug 1, 1996, 3:00:00 AM8/1/96
to

Hi Erhard,

27 Jul 96 11:41, Erhard Schwenk wrote to Markus Mattes:

MM>> Vorschlag: ein break; + Setzen eines Abbruchflags in der inneren

MM>> und eine Abfrage dieses Abbruchflags in der aeusseren Schleife.

MM>> Oder ein goto. :-) Tu Dir da nur keinen Zwang an. ;-)

ES> Beides mieser Stil und _verboten_ fuer einen ordentlichen
ES> Programmierer (und bei sauberer Entwicklung mittels A- und D-Tools
ES> auch gar nicht machbar).

1.) Stil ist Geschmacksache
2.) Ein "ordentlicher Programmierer" ist undefined. (Wenn schon haettest Du
sagen muessen "... fuer einen ordentlichen Programmierer nach Erhard Schwenks
Definition..." )
3.) Weisst Du, wohin Du Dir Deine sogn. saubere Entwicklung und Deine
vielgepriesenen A- und D-Tools stecken kannst? ;-)

Wo sind bloss die ganzen Programmierer hin und wo kommen die ganzen Designer
her? Erstere bitte wiederkommen, letztere bitte in's Modefach wechseln. ;-))

PS: 3.) bitte nicht missverstehen. :-)

ByE/2,
MarKus.

--- (c) Frobozz Magic Tearline Company
* Origin: xxx (2:2454/505.69)

Markus Mattes

unread,
Aug 1, 1996, 3:00:00 AM8/1/96
to

Hi Erhard,

27 Jul 96 11:43, Erhard Schwenk wrote to Markus Mattes:

[...]


MM>> Was man nicht alles tut, um nicht dieses verpoente "goto" zu

MM>> benutzen. :-)

Nochmal mein Beispiel, damit man den Thread besser verfolgen kann:

void foo(void) {
while(1) {
if(nobrain) break;
/*...*/
if(nocat) break;
/*...*/
if(nojoke) break;
/*...*/
break;
}
}

Uebrigens besser waere:

void foo(void) {
do {
/* Wie oben */
} while(0);
}

ES> Was du machst, ist strukturiert betrachtet auch nicht besser.

Natuerlich nicht. Obiges Beispiel stammt aus einem Beispielsource eines
namhaften Soft- und Hardwareherstellers, der IMO zeigt, wie "igitt" goto fuer
manche ist, und dass durch krampfhafte Vermeidung von goto nicht unbedingt was
besseres rauskommt. Die Betonung lag auf "krampfhaft".

Das geht dann soweit, dass der Compiler des oben erwaehnten Herstellers bei
allen eingeschalteten Warungen auch sowas als Warnung ausgibt:

test.c(11:18) : warning EDC0837: goto statement encountered.

Ich konnte nicht anders als mich lachend am Boden zu waelzen. :-) Wann ist es
endlich soweit, dass Programme abbrechen mit der Meldung: "Error 0815: JMP
Instruction encountered."? ;-)

ES> Dadurch, dass du goto durch ein anderes Wort (hier break) ersetzt,
ES> ist der strukturfehler noch lange nicht behoben. Der Code hat genau
ES> die gleichen Probs wie ein mit goto's gesetzter Code.

Der Code IST der gleiche, wie der mit goto (ich habe nachgesehen). :-) break
bzw. continue SIND gotos.

ES> Bessere Variante siehe andere Mail von gestern. Es geht nicht darum,
ES> das Wort "goto" zu vermeiden, sondern die Struktur "Sprung" bzw.
ES> "Unbedingter Sprung" nicht zu verwenden.

Das ist mir alles klar, aber anscheinend vielen nicht, die goto solcherart
umgehen... wie gesagt, das Beispiel stammt nicht von mir.

Allerdings benutze auch ich goto dort, wo es (mir) passt und habe da keinerlei
Beruehrungsaengste. ;-) Evtl. liegt das daran, dass ich, bevor ich C lernte
schon Assembler programmierte und ohne goto erntest Du da nichtmal eine gruene
Banane. Gut, ich muss gestehen, dass ich in meinen bisherigen C-Progs kein
einziges goto verwendete, dafuer aber massenweise breaks und continues und auch
da habe ich kein schlechtes Gewissen. ;-)

ES> Beides ist eigentlich schon Aufgabe der Design-Phase.

Am wichtigsten ist IMO das Ergebnis und die Effizienz (entgegen anderen
Behauptungen ;-) ) und nicht das Design. Wir sind doch nicht in der Modebranche
(oder habe ich den Zug schon verpasst?).

Erhard Schwenk

unread,
Aug 3, 1996, 3:00:00 AM8/3/96
to

Hallo Olaf!

OG> Wie wuerdest Du das Problem denn loesen? Oder allgemein, wie beendest Du
OG> verschachtelte Schleifen?

Das hatten wir schon ein paarmal hier im Echo, deshalb ganz kurz:

z.B. durch Setzen eines Ende-Merkers, der in jeder Bedingung mit ner
Und-Verknuepfung durchgeschleift wird. Das ist auch das Ergebnis, was die
meisten CASE-Tools erzeugen duerften. Man kann aber auch durch die Anordnung
der Schleife etwas optimieren.

Erhard Schwenk

unread,
Aug 3, 1996, 3:00:00 AM8/3/96
to

Hallo Markus!


MM> Am wichtigsten ist IMO das Ergebnis und die Effizienz (entgegen anderen
MM> Behauptungen ;-) ) und nicht das Design. Wir sind doch nicht in der
MM> Modebranche (oder habe ich den Zug schon verpasst?).

Das Design ist aus mehreren Gruenden _wichtig_.

1) Es ist die einzige Methode, um mit Sicherheit auf eine funktionierende
Loesung zu kommen.

2) Es ist Bestandteil der Dokumentation. Und Code ohne Doku ist spaetestens bei
der Wartung wertlos.

3) Es hilft eben, solche Fehler zu vermeiden.

In professionellen Projekten gibt es z.B. durchaus bereits Tests mit dem
(teilweise) fertigen Design, die Aussagen ueber die Effektivitaet (nicht
Effizienz!) des Codes treffen koennen. Und wenn man da feststellt, dass das
Design Muell ist, wird neu gearbeitet, bevor man eine Zeile Code geschrieben
hat.

Uebrigens: Fehler, die man bei der Implementierung oder beim Test findet, sind
viel teurer als solche, die in der Analyse- oder Design-Phase gefunden werden.
Auch das ein Argument fuer das Design vor der Programmierung. In grossen
Projekten nehmen Analyse und Design deshalb auch 80% der Arbeitszeit ein. Nur
der Rest geht auf Implementierung und Einfuehrung.

Erhard Schwenk

unread,
Aug 3, 1996, 3:00:00 AM8/3/96
to

Hallo Markus!

MM> 1.) Stil ist Geschmacksache

Stil wird im Style-Guide des jeweiligen Projektes definiert.

MM> 3.) Weisst Du, wohin Du Dir Deine sogn. saubere
MM> Entwicklung und Deine vielgepriesenen A- und D-Tools stecken kannst? ;-)

MM> Wo sind bloss die ganzen Programmierer hin und wo kommen die ganzen
MM> Designer her? Erstere bitte wiederkommen, letztere bitte in's Modefach
MM> wechseln. ;-))

Gott sei Dank setzt sich die Erkenntnis langsam durch, dass das Design _vor_
dem Programm kommt. Anders kann man grosse Projekte eben nicht mehr handeln. Ob
man das mit Tools oder haendisch macht, ist zweitrangig. Wichtig ist, dass man
mit Methode vorgeht. Das geht auch mit Papier und Bleistift. Und auch dann
produzierst du keine GOTO's. Es sei denn, du benutzt z.B. die daemlichen
Ansi-Erweiterungen der Nassi-Shneidermann-Diagramme (die fuer break und
continue), die aber mit dem urspruenglichen Programm bzw. mit strukturierter
Entwicklung nichts mehr zu tun haben. Die kommen daher, dass einige Leute
meinten, man muesste jedes Stueck Code mit so nem Diagramm darstellen koennen.
Das ist aber nicht Sinn der Sache. Man kann jedes Problem mit so einem Diagramm
darstellen und man kann jedes korrekte Diagramm direkt in Code umsetzen. Dabei
werden aber diese Anweisungen nicht vorkommen.

MM> PS: 3.) bitte nicht missverstehen. :-)

nee, schon recht ;)

Rainer Huebenthal

unread,
Aug 3, 1996, 3:00:00 AM8/3/96
to

Bonjour Erhard,

RH>> Einspruch. Sehr wohl machbar.

ES> Dann hast du schlechte Tools.

Das mache ich dir mit jedem Tool. Wenn man unbedingt will, kriegt
man sowas immer rein.

Thomas Seeling

unread,
Aug 4, 1996, 3:00:00 AM8/4/96
to

Hallo, Matthias!

*** Am Donnerstag 01. August 1996 um 08:40 schrieb Matthias Thiele an Thomas
Seeling:

MT> Fuer den Fall while (!i && j) bzw while (i && j) wird
MT> auf alle modernen Compiler uebertragbar ist.
Na gut :-).

Die Kenntnis der deMorgan'schen Regeln ist aber nach wie vor sehr nuetzlich.
Ich bin mir sicher, dass hier schon ganz gut gespart werden kann.

MT> diesem Fall sagen: es ist ziemlich unelegant in einer Schleifenbedingung
MT> extra alles umzudrehen nur um den Compiler die Optimierung einer Negation
MT> zu ersparen :-).
Nicht umdrehen, sondern gleich so programmieren.

Rainer Huebenthal

unread,
Aug 4, 1996, 3:00:00 AM8/4/96
to

Bonjour Markus,

MM> Am wichtigsten ist IMO das Ergebnis und die Effizienz

MM> (entgegen anderen Behauptungen ;-) ) und nicht das Design.

So hart darf man das IMHO nicht darstellen. Ein gutes Design
senkt Erweiterungskosten und sichert damit Auftraege. Auch die
Einarbeitung neuer Mitarbeiter wird vereinfacht. Allerdings
straeube ich mich auch, das (krampfhafte) Design ueberzubewerten.

Jan-Erik Rosinowski

unread,
Aug 4, 1996, 3:00:00 AM8/4/96
to

Moin Erhard!

ES> Es geht immer definitiv vernuenftig ohne gotos. Nimm ne richtige
ES> Design-Methode (wenns nicht grad OO sein muss, z.B. SADT oder so was in
ES> der Richtung) und du hast das Problem nicht. Und gleichzeitig hast du
ES> schon mit der Analyse und dem Design die halbe Doku fuer deinen Code
ES> geschrieben, musst nur noch ein Funktions- und Variablenverzeichnis
ES> anhaengen (vorausgesetzt, es existiert ein Pflichtenheft).

du kommst augenscheinlich nicht ab und an in den genuss, wildfremde
uraltsourcen zu warten?

ansonsten: ich habe das programmieren in pascal gelernt und knapp 10 jahre nie
ein goto verwendet. mittlerweile seh ichs relaxter und setze in anderer leute
sourcen, wenn sie eh beschissen strukturiert sind, auch gnadenlos gotos ein.
aber wie gesagt: mit dem try-except-finally-labeling.

Ciao, Jan

--- n/a
* Origin: Und taeglich gruesst das kleine Arschloch (2:2476/552.42)

Jan-Erik Rosinowski

unread,
Aug 4, 1996, 3:00:00 AM8/4/96
to

Moin Erhard!

K>> Das ist ja dann auch genau der Grund, warum man in Turbo-Pascal
K>> Dinge wie short circuit evaluation, Schleifenabbrueche und so
K>> weiter als Sprachelemente eingefuehrt hat: Damit aus einer
K>> Wandtafelsprache eines Algorithmenprofessors ein Werkzeug wird,
K>> das im taeglichen Gebrauch ueberleben kann.

ES> Diese scheinbaren Verkuerzungen erzeugen nicht nur nach meiner Erfahrung
ES> in Wahrheit nur Verlaengerungen bei den Wartungsarbeiten. Sie wurden auch
ES> nicht eingefuehrt, weil sie notwendig sind, sondern weil
ES> einige goto-verliebte BASIC- und C-Programmierer nicht in der Lage waren,
ES> den Gedanken der strukturierten Programmierung richtig zu verstehen
ES> und umzusetzen.

aha. wie uebersetzt du folgendes konstrukt in seiner ganzen klarheit in
iso-pascal?

p = listenanfang;

while (p && p->key != searchedkey) {
p = p->next;

Ortwin Gasper

unread,
Aug 4, 1996, 3:00:00 AM8/4/96
to

> Hi Erhard,
>

> 27 Jul 96 11:41, Erhard Schwenk wrote to Markus Mattes:

MM>>> Vorschlag: ein break; + Setzen eines Abbruchflags in der inneren
MM>>> und eine Abfrage dieses Abbruchflags in der aeusseren Schleife.

MM>>> Oder ein goto. :-) Tu Dir da nur keinen Zwang an. ;-)

ES>> Beides mieser Stil und _verboten_ fuer einen ordentlichen
ES>> Programmierer (und bei sauberer Entwicklung mittels A- und D-Tools
ES>> auch gar nicht machbar).

> 1.) Stil ist Geschmacksache

Es gibt IMHO Situationen, in denen die gezielte Verwendung eines goto die
Lesbarkeit und Wartbarkeit des Codes erhöht und in denen man zwanghafte
goto-Vermeidungskonstrukte nicht einsetzen sollte. Diese sind allerdings
relativ selten, z.B. beim Implementieren tail rekursiver Funktionen
(Beispiel auf Wunsch).
Andererseits können goto's sinnvoll sein, wenn der Sourcecode
maschinengeneriert und damit nicht von Hand zu warten ist, da dann die
einfache Codeerzeugung durch den x->C-Compiler im Vordergrund steht.
(Siehe z.B. Gambit-Scheme, Scheme->C etc.)
Insgesamt aber sollte der Einsatz dieses Sprachelementes auf solche
begründete Ausnahmesituationen beschränkt bleiben.

MfG
Ortwin

--- CrossPoint v3.11 R
* Origin: (2:2448/9020.48)

Rainer Huebenthal

unread,
Aug 5, 1996, 3:00:00 AM8/5/96
to

Bonjour Erhard,

ES> Das Design ist aus mehreren Gruenden _wichtig_.
ES>
ES> 1) Es ist die einzige Methode, um mit Sicherheit auf eine
ES> funktionierende Loesung zu kommen.

Falsch. Verkehrte Analyse -> verkehrtes Design -> verkehrte
Software. CASE verhindert nicht, dass dein Projekt _mit_
_Sicherheit_ auf eine funktionierende Loesung kommt. Wie kommst
du bloss da drauf ? CASE funktioniert a la GIGO : garbage in,
garbage out. Eine Kreissaege garantiert auch nicht, dass du aus
einem Holzblock einen Tisch bekommst.

ES> 2) Es ist Bestandteil der Dokumentation. Und Code ohne Doku
ES> ist spaetestens bei der Wartung wertlos.

Wertlos nicht, aber sehr teuer.

ES> 3) Es hilft eben, solche Fehler zu vermeiden.

Nein. Siehe GIGO. Es kommt immer darauf an, _wer_ das Design
macht. Nicht das Desgin per se vermeidet Fehler.

ES>
ES> In professionellen Projekten gibt es z.B. durchaus bereits
ES> Tests mit dem (teilweise) fertigen Design, die Aussagen
ES> ueber die Effektivitaet (nicht Effizienz!) des Codes treffen
ES> koennen.

Wie designt ihr bloss ? Das Design legt mitnichten irgendwelchen
CODE fest. Kodieren kommt _nach_ dem Design, das ist naemlich die
Construction Phase.

ES> Und wenn man da feststellt, dass das Design Muell
ES> ist, wird neu gearbeitet, bevor man eine Zeile Code
ES> geschrieben hat.

Das ist das Prinzip der Meilensteine. Jede Phase bildet einen
Meilenstein. Bei Fehlern ist immer bis zum naechsten Meilenstein
zurueckzugehen.

ES> Uebrigens: Fehler, die man bei der Implementierung oder beim
ES> Test findet, sind viel teurer als solche, die in der
ES> Analyse- oder Design-Phase gefunden werden. Auch das ein
ES> Argument fuer das Design vor der Programmierung. In grossen
ES> Projekten nehmen Analyse und Design deshalb auch 80% der
ES> Arbeitszeit ein. Nur der Rest geht auf Implementierung und
ES> Einfuehrung.

Von der Sicht der Applikationserstellung scheint diese Aufteilung
korrekt. Bei Grossprojekten ist die Einteilung in Analyse, Design
und Implementierung jedoch viel zu grob, so daß auch die 80 &
nicht mehr gelten. Hinter einer Applikation haengt schliesslich
mehr als nur ein Sack von Programmen.


au revoir
Rainer


--- CrossPoint v3.11 R

Rudolf Patzner

unread,
Aug 6, 1996, 3:00:00 AM8/6/96
to

In <MSGID_2=3A244=2F1130.42...@fidonet.org>, Thomas_Seeling%p42.f1130.n244...@bb.maus.de (Thomas Seeling) writes:
>Hallo, Matthias!
>
>*** Am Donnerstag 01. August 1996 um 08:40 schrieb Matthias Thiele an Thomas
>Seeling:
>
> MT> Fuer den Fall while (!i && j) bzw while (i && j) wird
> MT> auf alle modernen Compiler uebertragbar ist.
>Na gut :-).
>
>Die Kenntnis der deMorgan'schen Regeln ist aber nach wie vor sehr nuetzlich.
>Ich bin mir sicher, dass hier schon ganz gut gespart werden kann.
>
> MT> diesem Fall sagen: es ist ziemlich unelegant in einer Schleifenbedingung
> MT> extra alles umzudrehen nur um den Compiler die Optimierung einer Negation
> MT> zu ersparen :-).
>Nicht umdrehen, sondern gleich so programmieren.
>
>
>Tschau...Thomas>

Guten Tag,

meine eiserne Regel:
niemals irgendwas verkomplizieren, nur weils fuer den compiler
einfacher oder (scheinbar) effizienter ist, es sei denn,
es bringt wirklich einen signifikanten Gewinn (und das
ist wirklich aeuserst selten).

Also: immer so programmieren, dass mans lesen kann und der Quellkode
dann sauber strukturiert ist.

Ciao,
Marcus

kris

unread,
Aug 6, 1996, 3:00:00 AM8/6/96
to

Erhard_...@p65.f3001.n2487.z2.fidonet.org (Erhard Schwenk) writes:
> K> sind gaengige Redewendungen in C und das seit Jahrzehnten.
> K> Programmcode dieser Form zieht sich zum Beispiel durch von den
> K> Quellen fuer den UNIX V7 Kernel und die dazugehoerenden
> K> Utilities bis hin zu aktuellen Versionen von 4.4BSD und Linux.
> K> Und das, obwohl sich der Programmierstil ansonsten ziemlich
> K> radikal gewandelt hat (das ist eine andere, nicht minder
> K> interessante Geschichte).

>Erstens sind diese Konstruktionen uralt, zweitens haben sie mit Struktur
nichts
>zu tun und drittens sind genau das die Konstruktionen, die heute eine Wartung
>z.B. alter COBOL-Software nahezu unmoeglich und deshalb eine Neuentwicklung
>vieler Softwarepakete noetig machen.

Nun, Du hattest nach altem Code gefragt (eigentlich hattest Du
gefragt, was mit der Wartung von 20 Jahre altem Code ist und
ich hatte das zum Anlass genommen, ein 20 Jahre altes
PDP11-Band einzulesen und Dir ein wenig 20 Jahre alten Code zu
zitieren). So schwer zu warten koennen solche Konstrukte auch
nicht sein, denn in hoechst modernem und objektorientiert
strukturiertem Linux (ja, in C geschrieben) findest Du exakt
dieselben Ideome. Diese Redewendungen (Waechter-Returns und
Schleifenkurzschluesse, Exception-Handling mit goto's) muessen
die allgemeine Brauchbarkeitsrelation sehr gut erfuellen, wenn
sie sich so lange halten.

Und ein typischer Betriebssystemkernel ist auch nicht wirklich
ein kleines, leicht zu verstehendes Programm. Wenn ausgerechnet
*da* solche Konstruktionen massenhaft verwendet werden, dann
muessen sie etwas fuer sich haben. Oder, um
/usr/src/linux/Documentation/CodingStyle zu zitieren:

The answer to that is that if you need more than 3
levels of indentation, you're screwed anyway, and
should fix your program.

Die genannten goto's und goto-aehnlichen Konstrukte sind exakt
die Werkzeuge, mit denen man den indentation level seiner
Sourcen gering haelt und mit denen man den normal path of
execution straight haelt. Das hilft vor allen Dingen dem Lesen
und an einigen Stellen auch dem Compiler (das ist jedoch an den
meisten Stellen sekundaer).

>Die OOD-maessig hoechst umstritten ist und Quellcodes bereits heute schwer
>wartbar werden liess. Bis heute ist umstritten, ob Exceptions nun
>strukturmaessig sinnvoll oder gefaehrlich sind. Und nach dem, was ich bisher
>sah, welche Exceptions von manchen Leuten verbrochen werden, halte ich sie
eher
>fuer verboten.

Och, wenn Du auf dieser Tangente in die Umlaufbahn gehst, dann
solltest Du die Route auch zu Ende fliegen. Was ist mit if und
for? Das sind auch nur goto's im Abendkleid. Es waere
sicherlich viel interessanter, solche Strukturen auf zu
streichen und stattdessen ein typisiertes Lambda-Kalkuel
anzuwenden und if durch den y-Operator und for durch
endstaendige Rekursion zu ersetzen.

Das wuerde nebenbei auch noch so gefaehrliche Dinge wie
Seiteneffekte, Zeiger und konsequenterweise auch Variablen
generell abschaffen und waere eine grossartige Vereinfachung
beim Scheduling fuer symmetrische Multiprozessoren (da wir
keine Seiteneffekte mehr haben, koennen wir unabhaengige
Teilbaeume des Lambda-Ausdruckes leicht auf anderen Prozessoren
berechnen lassen). Und weil das beweistechnisch auch viel
einfacher zu handhaben ist, koennten wir den Pfad aus der
Designphase in die Codierungsphase auch weitergehender
automatisieren.

Dass das nicht einmal annaehernd realistisch ist, muessen
inzwischen sogar die Herren Langmaak und Kluge an der Uni Kiel
zugeben.

>Sie ist nicht nur vollstaendig, sondern auch sinnvoll. Es ist nachgewiesen,
>dass jedes mit "goto" und "unstrukturierten" Mitteln loesbare Problem auch
eine
>strukturierte Loesung hat, darueber gibts auch ne Doktorarbeit.

Korrekt. Und jede dieser goto-freien Loesungen ist direkt auf
eine Turing-Maschine uebertragbar, wie man leicht zeigen kann.
Die einzige Operation der Turing-Maschine ist jedoch das goto,
obendrein noch eines mit Seiteneffekten. So what?

>Im Gegenteil, alles andere ist unuebersichtlich und Muell. Ich weiss nicht, wo
>du programmierst, aber solcher Code wuerde bei mir in der Firma direkt in der
>Tonne landen. Gottseidank.

Ich arbeite zum Glueck nicht in einer Firma, in der
kaufmaennische C/S-Datenbankanwendungen erstellt werden
muessen. Ich hatte immer schon Schwierigkeiten damit, Programme
zu schreiben, deren Aufgabe die Summation endloser
Datenbankspalten und die abschliessende Multiplikation mit 1.15
ist. :-)

Ich arbeite bei einem Internet-Provider. Meine Aufgaben sind
Schulung, Beratung und Entwicklung, vorzugsweise im
Kernel/Geraetetreiber-Umfeld.

>ps: Mit deinem Absender scheint was nicht zu stimmen.

Nein, der ist in Ordnung. Es ist das Fido-Gateway und das
Datenformat von Fido, die nicht in Ordnung sind.

Kristian
--
Kristian Koehntopp, Wassilystrasse 30, 24113 Kiel, +49 431 688897
Sie haben sich auf der Grundlage harter Fakten eine feste Meinung
gebildet? Posten Sie sie doch einfach mal nach de.talk.bizarre.
Die kriegen dort beides wieder weich.

--- FIDOGATE 3.9.3
* Origin: Fido-Gateway @ white.schulung.netuse.de (2:240/2123.59)

Horst Kraemer

unread,
Aug 7, 1996, 3:00:00 AM8/7/96
to

Hallo Erhard,

17 Jul 96 17:15:35, <Erhard Schwenk> to <Michael Ringel>:

> ES>> GOTO ist ein
> ES>> Befehl, der in keinem, aber absolut keinem Programm irgendeine
> ES>> Berechtigung haette.

> MR> ... und damit geht die Diskussion in die theologische Ebene ueber. Ich
> MR> sehe diese Sache viel relaxter: Wenn Du goto brauchst, nimmst Du goto.

> Du brauchst es eben nicht. Wenn du ein goto (scheinbar) brauchst, ist
> das schon ein Beweis fuer ein mangelhaftes Design, wenn du das Goto
> nicht durch eine saubere if- oder while-Konstruktion ersetzen kannst.

Kleine Programmierer haben kleine Probleme. Ein weiter Horizont kann auch
manchmal einengen ;-), was nicht heissen soll, dass ich Deine Argumente
ablehne.

Genau _das_ ist Theologie. Der Grossinquisitor sprach: "Wer Goto benutzt, ist
ein Haeretiker". Dein _Beweis_ bezieht sich auf Dein Axiomensystem.

Manchmal waere es geradezu befreiend, wenn nicht jede Diskussion ueber C-Syntax
auf wundersame Weise im Yang-Tse-Kiang des Software-Engeneering endete ;-)


Herzlichst
Horst

--- FMail 1.02
* Origin: -= Berlin, tierra florida =- (2:2410/249.5)

Erhard Schwenk

unread,
Aug 7, 1996, 3:00:00 AM8/7/96
to

Hallo Rainer!

MM>> Am wichtigsten ist IMO das Ergebnis und die Effizienz
MM>> (entgegen anderen Behauptungen ;-) ) und nicht das Design.

RH> So hart darf man das IMHO nicht darstellen. Ein gutes Design
RH> senkt Erweiterungskosten und sichert damit Auftraege. Auch die
RH> Einarbeitung neuer Mitarbeiter wird vereinfacht. Allerdings
RH> straeube ich mich auch, das (krampfhafte) Design ueberzubewerten.

Das ist keine Ueberbewertung, sondern die korrekte Bewertung. Ein Design macht
wirklich nur Sinn, wenn es konsequent durchgezogen wird. Jede Abweichung raecht
sich irgendwann.

Erhard Schwenk

unread,
Aug 7, 1996, 3:00:00 AM8/7/96
to

Hallo Jan-Erik!


JR> du kommst augenscheinlich nicht ab und an in den genuss, wildfremde
JR> uraltsourcen zu warten?

Nun, genau das ist im Moment eines meiner Probleme. Genau solche sourcen darf
ich gerade warten (COBOL-74-Programme ohne Kommentare und Doku, der Quellcode
enthaelt keine einzige Leerzeile, Einrueckungen wild durcheinander und
numerische Labels und Variablennamen), und da habe ich genau das Problem mit
derartigen unnoetigen goto's (teilweise gehts in COBOL-74 aber auch nicht
anders, weil z.B. die IF-Konstruktion nicht richtig verschachtelt werden kann
:((( ). Und genau deshalb bin ich dafuer, die Schluesselworte goto, break,
continue usw. (bzw. die entsprechenden Konstrukte) aus _allen_ Sprachen
ersatzlos zu streichen bzw. in jeder Code-Richtlinie ohne Ausnahme zu
verbieten.

JR> ansonsten: ich habe das programmieren in pascal gelernt und knapp 10 jahre
JR> nie ein goto verwendet. mittlerweile seh ichs relaxter und setze in
JR> anderer leute sourcen, wenn sie eh beschissen strukturiert sind, auch
JR> gnadenlos gotos ein.

Da ist eh Hopfen und Malz verloren.

JR> aber wie gesagt: mit dem try-except-finally-labeling.

Das versuche ich in neuen Sourcen inzwischen eben zu vermeiden, weil es mich
immer wieder auf kleinere Probleme gebracht hat. Gerade in C, wo man doch
vielleicht noch Speicher freigeben muss oder das System aufraeumen.

Erhard Schwenk

unread,
Aug 7, 1996, 3:00:00 AM8/7/96
to

Hallo Jan-Erik!

JR> aha. wie uebersetzt du folgendes konstrukt in seiner ganzen klarheit in
JR> iso-pascal?

JR> p = listenanfang;

JR> while (p && p->key != searchedkey) {
JR> p = p->next;
JR> }

Das ist das Problem der Circuit-Evaluation. Das hatte ich eigentlich weniger
gemeint. Mir ging es vor allem um die break-, continue- und
exit-Konstruktionen. Obiges kannst du ja auch in einem Struktogramm problemlos
darstellen. Das wurde bei der Entwicklung von Pascal sicher uebersehen. Auch
wenn es da wohl eine Standard-Umgehung gibt. Aber derartige Konstruktionen sind
auch strukturell nirgends irgendwie unsauber, oder?

Nur die exit-, continue- und break-Konstruktionen sind eigentlich sehr
bedenklich. Das einzige break, das in C-Programmen seine Berechtigung hat,
steht in ner switch-Konstruktion (da hat es aber eher die Funktion eines end
case). Man haette das allerdings syntaktisch vielleicht eher mit { und } loesen
sollen, und damit auch gleich eine weitere Fehlerquelle eliminiert, die sowieso
strukturell wieder bedenklich ist.

Erhard Schwenk

unread,
Aug 7, 1996, 3:00:00 AM8/7/96
to

Hallo Rainer!

RH> Bonjour Erhard,

RH>>> Einspruch. Sehr wohl machbar.

ES>> Dann hast du schlechte Tools.

RH> Das mache ich dir mit jedem Tool. Wenn man unbedingt will, kriegt man
RH> sowas immer rein.

Nun ja, z.B. mit ARIS muss man da aber ganz schoene Klimmzuege machen.
Zumindest geht das nur mit mutwilliger Vorsaetzlichkeit.

Markus Mattes

unread,
Aug 8, 1996, 3:00:00 AM8/8/96
to

Hi Rainer,

04 Aug 96 00:00, Rainer Huebenthal wrote to Markus Mattes:

[...]


RH> So hart darf man das IMHO nicht darstellen. Ein gutes Design
RH> senkt Erweiterungskosten und sichert damit Auftraege. Auch die
RH> Einarbeitung neuer Mitarbeiter wird vereinfacht. Allerdings
RH> straeube ich mich auch, das (krampfhafte) Design ueberzubewerten.

Einverstanden.

Markus Mattes

unread,
Aug 8, 1996, 3:00:00 AM8/8/96
to

Hi Erhard,

03 Aug 96 22:44, Erhard Schwenk wrote to Markus Mattes:

MM>> 1.) Stil ist Geschmacksache
ES> Stil wird im Style-Guide des jeweiligen Projektes definiert.

Was immer noch nichts an der Tatsache aendert, dass es Geschmacksache ist. :-)
Nur weil es dann die Geschmacksache von MEHREREN Personen ist, ist es noch
lange nicht fuer den Rest der Welt bindend.

[...]
ES> Gott sei Dank setzt sich die Erkenntnis langsam durch, dass das
ES> Design _vor_ dem Programm kommt. Anders kann man grosse Projekte eben
ES> nicht mehr handeln. Ob man das mit Tools oder haendisch macht, ist
ES> zweitrangig. Wichtig ist, dass man mit Methode vorgeht.

Agree.

ES> Das geht auch mit Papier und Bleistift. Und auch dann produzierst du
ES> keine GOTO's.

Kein Agree mehr. Das kommt ganz darauf an, wie tief ich mein Design ansetze. Es
kann durchaus sein, dass mein Design nur bis zur Funktionsebene kommt.

Z.B setze ich mich nicht hin und zeichne irgendwelche Diagramme fuer eine
popelige Strcpy-Funktion (nur ein Beispiel). Da kommt mein Design genau bis
char *strcpy(char *ziel, const char *quelle). Und ob in einer solchen Funktion
dann irgendwo ein goto auftaucht, wird Dir spaeter nicht den Hals brechen,
glaube mir.

Ich bestreite auch gar nicht, dass Design sehr wichtig ist, ich wehre mich nur
dagegen es ueber alles andere zu erheben, so wie Du es IMO tust.

Erhard Schwenk

unread,
Aug 8, 1996, 3:00:00 AM8/8/96
to

Hallo Kristian!

K> Nun, Du hattest nach altem Code gefragt (eigentlich hattest Du
K> gefragt, was mit der Wartung von 20 Jahre altem Code ist und
K> ich hatte das zum Anlass genommen, ein 20 Jahre altes
K> PDP11-Band einzulesen und Dir ein wenig 20 Jahre alten Code zu
K> zitieren). So schwer zu warten koennen solche Konstrukte auch
K> nicht sein, denn in hoechst modernem und objektorientiert
K> strukturiertem Linux (ja, in C geschrieben) findest Du exakt
K> dieselben Ideome. Diese Redewendungen (Waechter-Returns und
K> Schleifenkurzschluesse, Exception-Handling mit goto's) muessen
K> die allgemeine Brauchbarkeitsrelation sehr gut erfuellen, wenn
K> sie sich so lange halten.

Das ist IMHO eher ein Argument fuer die Betonkoepfe, die in vielen Bereichen
der EDV heute noch sitzen und arbeiten wie vor 20 Jahren und fuer die
Unwilligkeit (oder -faehigkeit?) vieler Informatik-Studenten, strukturierte
Programmierung richtig zu kapieren (sonst wuerden sie gar nicht auf goto-Ideen
kommen). Wie wollen die erst OO kapieren?

K> Und ein typischer Betriebssystemkernel ist auch nicht wirklich
K> ein kleines, leicht zu verstehendes Programm. Wenn ausgerechnet
K> *da* solche Konstruktionen massenhaft verwendet werden, dann
K> muessen sie etwas fuer sich haben. Oder, um
K> /usr/src/linux/Documentation/CodingStyle zu zitieren:

K> The answer to that is that if you need more than 3
K> levels of indentation, you're screwed anyway, and
K> should fix your program.

K> Die genannten goto's und goto-aehnlichen Konstrukte sind exakt
K> die Werkzeuge, mit denen man den indentation level seiner
K> Sourcen gering haelt und mit denen man den normal path of
K> execution straight haelt. Das hilft vor allen Dingen dem Lesen
K> und an einigen Stellen auch dem Compiler (das ist jedoch an den
K> meisten Stellen sekundaer).

Indentation ist IMHO das kleinere Uebel. Wenn der Quellcode sauber und nach
festen Regeln formatiert wird, kann man das ohne Weiteres lesen. Uebrigens: Ein
goto aus einer Verschachtelungsebene raus macht dem Compiler ganz erhebliche
Schwierigkeiten, denn er muss da erstmal ermitteln, wie weit der Stack
aufzuraeumen ist.

K> Och, wenn Du auf dieser Tangente in die Umlaufbahn gehst, dann
K> solltest Du die Route auch zu Ende fliegen.

Sie ist bereits am Ende

K> Was ist mit if und
K> for? Das sind auch nur goto's im Abendkleid.

Richtig. Aber es geht nicht um die Vermeidung des Wortes goto, sondern um
Vermeidung aller Konstruktionen, die nicht auf if oder for basieren. Jeder
Sprung ohne Rueckkehr aus einem Strukturblock heraus ist gefaehrlich (und
deshalb verboten), ein Block hat einen Eingang und einen Ausgang. Deshalb auch
die Aussagen gegen break, continue usw.

K> Es waere
K> sicherlich viel interessanter, solche Strukturen auf zu
K> streichen und stattdessen ein typisiertes Lambda-Kalkuel
K> anzuwenden und if durch den y-Operator und for durch
K> endstaendige Rekursion zu ersetzen.

Nun, Rekursion ist wohl noch bedenklicher. Du gehst in die falsche Richtung?
Der Ersatz von goto durch for und if fuehrt zu einer Spezialisierung. Was du
machst, ist IMHO eigentlich eine Generalisierung, oder? Du schraenkst ja nicht
ein, sondern du weitest aus.

K> Das wuerde nebenbei auch noch so gefaehrliche Dinge wie
K> Seiteneffekte,

Die sind sowieso schon in der Namenskonvention verboten.

K> Zeiger

Sind nur gekapselt in Modulen oder Klassen ueberhaupt zulaessig.

K> und konsequenterweise auch Variablen
K> generell abschaffen und waere eine grossartige Vereinfachung
K> beim Scheduling fuer symmetrische Multiprozessoren (da wir
K> keine Seiteneffekte mehr haben, koennen wir unabhaengige
K> Teilbaeume des Lambda-Ausdruckes leicht auf anderen Prozessoren
K> berechnen lassen). Und weil das beweistechnisch auch viel
K> einfacher zu handhaben ist, koennten wir den Pfad aus der
K> Designphase in die Codierungsphase auch weitergehender
K> automatisieren.

Es gibt Code-Generatoren, die genau diesen Weg verfolgen. Und sie sind nicht
die schlechtesten ;).

K> Korrekt. Und jede dieser goto-freien Loesungen ist direkt auf
K> eine Turing-Maschine uebertragbar, wie man leicht zeigen kann.
K> Die einzige Operation der Turing-Maschine ist jedoch das goto,
K> obendrein noch eines mit Seiteneffekten. So what?

Richtig. Aber das goto ist eine Generalisierung von if und for (eigentlich
wieder nicht, denn jede Konstruktion ist ja mit if und for loesbar!), if und
for stellen sozusagen eine normalisierte Form von goto dar. Und Polynome werden
z.B. ja auch bevorzugt in einigen standardisierten (normalisierten) Formen
dargestellt, wenn man sie berechnen will. Diese normalisierte (Normal-?) Form
stellt also eine allgemein gueltige und lesbare Schreibweise dar, aus der
bestimmte Eigenschaften (etwa das Programmende) direkt abgelesen werden
koennen. Und darum geht es. Wenn ich am Abi als Loesung einer Mathe-Aufgabe
hinschreibe 3x+5y = 7 x^ 2 - 3 y, dann bekomm ich dafuer nen Fehler. Und das
zurecht. Warum soll das bei komplexeren Dingen wie Computerprogrammen anders
sein?

K> Ich arbeite zum Glueck nicht in einer Firma, in der
K> kaufmaennische C/S-Datenbankanwendungen erstellt werden
K> muessen. Ich hatte immer schon Schwierigkeiten damit, Programme
K> zu schreiben, deren Aufgabe die Summation endloser
K> Datenbankspalten und die abschliessende Multiplikation mit 1.15
K> ist. :-)

Das ist wohl nur ein Teil der Aufgaben, die da anfallen. Auch im BWL-Bereich
gibt es durchaus ernstzunehmende algorithmische und mathematische Probleme, und
auch die sollen in solchen Anwendungen letztendlich verarbeitet werden. Von den
Problemen von verteilter Datenhaltung und Multiuser-Umgebungen mal abgesehen.
Schonmal ein wenig Finanzmathematik gesehen? Ich meine jetzt nicht das
Sachrechnen aus der 10. Klasse, sondern so richtig schoene OR-Probleme.

K> Ich arbeite bei einem Internet-Provider. Meine Aufgaben sind
K> Schulung, Beratung und Entwicklung, vorzugsweise im
K> Kernel/Geraetetreiber-Umfeld.

Nun, da hast du das Problem doch noch viel dicker. Wie willst du in einem
Assembler-Geraetetreiber jemals ordentlich Diagnose und Debugging betreiben
koennen, wenn du die einfachsten Strukturregeln nicht einhaelst? Wie soll der
Nachfolger auf deinem Arbeitsplatz jemals die sourcen warten koennen? Man wird
dich nicht befoerdern, weil sonst die Software rausgeschmissen werden muss ;).

K> Nein, der ist in Ordnung. Es ist das Fido-Gateway und das
K> Datenformat von Fido, die nicht in Ordnung sind.

Nun, das Datenformat von Fido existiert per Definition und kann daher nicht
falsch oder richtig sein, hoechstens sinnvoll oder sinnlos. Also wird es wohl
das Gateway sein.

MfG, Erhard.

Markus Mattes

unread,
Aug 8, 1996, 3:00:00 AM8/8/96
to

Hi Erhard,

03 Aug 96 22:49, Erhard Schwenk wrote to Markus Mattes:

MM>> Am wichtigsten ist IMO das Ergebnis und die Effizienz (entgegen
MM>> anderen Behauptungen ;-) ) und nicht das Design. Wir sind doch
MM>> nicht in der Modebranche (oder habe ich den Zug schon verpasst?).

ES> Das Design ist aus mehreren Gruenden _wichtig_.

[...]

Dass es wichtig ist, bestreitet wohl niemand... was ich bestreite ist, dass es
DAS WICHTIGSTE ist.

Erhard Schwenk

unread,
Aug 11, 1996, 3:00:00 AM8/11/96
to

Hallo Rainer!

RH> Falsch. Verkehrte Analyse -> verkehrtes Design -> verkehrte
RH> Software. CASE verhindert nicht, dass dein Projekt _mit_
RH> _Sicherheit_ auf eine funktionierende Loesung kommt. Wie kommst du bloss
RH> da drauf ? CASE funktioniert a la GIGO : garbage in, garbage out. Eine
RH> Kreissaege garantiert auch nicht, dass du aus einem Holzblock einen
RH> Tisch bekommst.

Nein, aber sie ist das einzige vernuenftige Mittel, um nicht mit grosser
Sicherheit Saegemehl zu erzeugen. Das hatte ich wohl etwas falsch ausgedrueckt.
Tatsache ist, ohne saubere Analyse und sauberes Design kommst du in 99% der
Faelle auf keinen gruenen Zweig.

ES>> 2) Es ist Bestandteil der Dokumentation. Und Code ohne Doku
ES>> ist spaetestens bei der Wartung wertlos.

RH> Wertlos nicht, aber sehr teuer.

Und damit in der Praxis eben wertlos. Denn es ist dann meist billiger, das
ganze nochmal zu schreiben, womit der alte Code definitiv wertlos wird.

RH> Nein. Siehe GIGO. Es kommt immer darauf an, _wer_ das Design
RH> macht. Nicht das Desgin per se vermeidet Fehler.

Wenn man die Design-Methode beherrscht, schon. Natuerlich setzt das Anwenden
einer Design-Methode voraus, dass man diese auch kapiert hat. Aber wenn man
dann weiss, was man will, ist die Chance, absoluten Muell zu produzieren schon
um einiges kleiner.

ES>> In professionellen Projekten gibt es z.B. durchaus bereits
ES>> Tests mit dem (teilweise) fertigen Design, die Aussagen
ES>> ueber die Effektivitaet (nicht Effizienz!) des Codes treffen
ES>> koennen.

RH> Wie designt ihr bloss ? Das Design legt mitnichten irgendwelchen CODE
RH> fest. Kodieren kommt _nach_ dem Design, das ist naemlich die
RH> Construction Phase.

Diese Tests werden _nicht_ mit Code gemacht. Sie werden mit dem Ergebnis der
Design-Phase z.B. anhand von Modellrechnungen gemacht. Man kann durchaus (auch
wenn sich das zunaechst etwas seltsam anhoert) bereits ein Design testen, ohne
eine Zeile Code geschrieben zu haben. Diese Funktion ist z.B. auch bei vielen
CASE-Tools integriert. Das Design legt ja im Prinzip bei konsequenter Anwendung
bereits jede einzelne Zeile Code nahezu fest (im Prinzip entspricht ein gutes
Design der Anwendung in System- und Sprachunabhaengiger Form). Da kann man mit
bestimmten Tests schon recht viel machen. Das hat _nichts_ mit Code zu tun.
Aber es koennen Aussagen bezueglich der Laufzeit getroffen werden, die
natuerlich nachher auch fuer den entstandenen Code (der ja im Prinzip durch das
Design bereits mehr oder weniger festgelegt wurde) zutreffen. Hier kann man
bereits feststellen, ob man ne groessere Maschine braucht oder nicht.

ES>> Und wenn man da feststellt, dass das Design Muell
ES>> ist, wird neu gearbeitet, bevor man eine Zeile Code
ES>> geschrieben hat.

RH> Das ist das Prinzip der Meilensteine. Jede Phase bildet einen
RH> Meilenstein. Bei Fehlern ist immer bis zum naechsten Meilenstein
RH> zurueckzugehen.

Richtig.

RH> Von der Sicht der Applikationserstellung scheint diese Aufteilung
RH> korrekt. Bei Grossprojekten ist die Einteilung in Analyse, Design und
RH> Implementierung jedoch viel zu grob, so daß auch die 80 & nicht mehr
RH> gelten. Hinter einer Applikation haengt schliesslich mehr als nur ein
RH> Sack von Programmen.

Selbstverstaendlich werden die Phasen bei groesseren Projekten mehr
aufgegliedert. Aber die Aussage, dass Fehler umso teurer werden, je spaeter sie
gefunden werden, stimmt trotzdem. Und wie gesagt, auch ein Design kann man
testen. Bei einfachen Funktionen "von hand", indem man z.B. die
Nassi-Shneidermann-Diagramme durchspielt, bei komplexeren Projekten natuerlich
mit entsprechenden Tools.

Erhard Schwenk

unread,
Aug 12, 1996, 3:00:00 AM8/12/96
to

Hallo Markus!


MM> Dass es wichtig ist, bestreitet wohl niemand... was ich bestreite ist,
dass
MM> es DAS WICHTIGSTE ist.

Habe ich nie behauptet. Es ist aber die Grundlage saubererer Arbeit, und damit
einfach unverzichtbar. Und auf jeden Fall wichtiger, als irgendwelche dubiose
Optimierungen.

Erhard Schwenk

unread,
Aug 12, 1996, 3:00:00 AM8/12/96
to

Hallo Markus!


MM> Was immer noch nichts an der Tatsache aendert, dass es Geschmacksache ist.
MM> :-) Nur weil es dann die Geschmacksache von MEHREREN Personen ist, ist es
MM> noch lange nicht fuer den Rest der Welt bindend.

Es ist fuer das Projekt bindend. Das ist ausreichend. Und es wird auch nicht
immer von mehreren Personen festgelegt. Ach ja: Und mit Geschmack hat das meist
auch herzlich wenig zu tun, mehr mit Erfahrung und Verstaendnis bestimmter
Techniken.

ES>> Das geht auch mit Papier und Bleistift. Und auch dann produzierst du
ES>> keine GOTO's.

MM> Kein Agree mehr. Das kommt ganz darauf an, wie tief ich mein Design
MM> ansetze. Es kann durchaus sein, dass mein Design nur bis zur
MM> Funktionsebene kommt.

Dann ist es unvollstaendig.

MM> Z.B setze ich mich nicht hin und zeichne irgendwelche Diagramme fuer eine
MM> popelige Strcpy-Funktion (nur ein Beispiel). Da kommt mein Design genau
MM> bis char *strcpy(char *ziel, const char *quelle). Und ob in einer solchen
MM> Funktion dann irgendwo ein goto auftaucht, wird Dir spaeter nicht den Hals
MM> brechen, glaube mir.

Oh doch, es kann. Ich habe sowas gerade erlebt, als ein altes COBOL-Programm
genau aus diesem Grunde 3 Tage Wartungsarbeit kostete, die sonst in 10 Minuten
erledigt gewesen waere. Ein schlichtes GOTO, das bei der Wartung uebersehen
wurde...

MM> Ich bestreite auch gar nicht, dass Design sehr wichtig ist, ich wehre mich
MM> nur dagegen es ueber alles andere zu erheben, so wie Du es IMO tust.

Ich erhebe es nicht ueber alles andere, sondern ich sage, es ist die Grundlage
guter Arbeit. Und ohne Fundament bringt bei nem Haus der schoenste Dachstuhl
nix.

Olaf Gerike

unread,
Aug 13, 1996, 3:00:00 AM8/13/96
to

Hallo Erhard,

>z.B. durch Setzen eines Ende-Merkers, der in jeder Bedingung mit ner
>Und-Verknuepfung durchgeschleift wird.

das ist aber auch nicht das gelbe vom Ei. Dabei steht die Fehlerbehandlung
mitten in der Funktion. Und die Vermischung von normaler Bearbeitung und
Fehlerbehandlung steigert auch nicht die Lesbarkeit.

tschüß, Olaf

Soenke Mueller-Lund

unread,
Aug 13, 1996, 3:00:00 AM8/13/96
to

Moin Erhard,

an der Diskussion wird sich wohl nicht mehr viel ändern. Du fürchtest
"goto" wie der Teufel das Weihwasser, während die anderen Teilnehmer weit
weniger dogmatisch programmieren.

Aber:

> Ein goto aus einer Verschachtelungsebene raus macht dem Compiler ganz
> erhebliche Schwierigkeiten, denn er muss da erstmal ermitteln, wie weit der
> Stack aufzuraeumen ist.

Soviel "gotos" kannst Du in deinem ganzen Leben nicht programmieren, die
summiert dem Compiler soviel Schwierigkeiten zufügen, daß Du in dieser
zusätzlichen Zeitspanne obigen Absatz schreiben kannst.

Ciao
Sönke

"My homepage is my castle"

Siegfried Weiss

unread,
Aug 14, 1996, 3:00:00 AM8/14/96
to

Hi Markus,

(ich beziehe mich auf Deine mail, da ich 4 Wochen offline war und die
Ursprungsmail nicht habe)

MM> ES> Das geht auch mit Papier und Bleistift. Und auch dann produzierst du
MM> ES> keine GOTO's.


MM>
MM> Kein Agree mehr. Das kommt ganz darauf an, wie tief ich mein Design

ansetze. Es
MM> kann durchaus sein, dass mein Design nur bis zur Funktionsebene kommt.

Richtig. Ich möchte es mal so formulieren:

Design und Implementierung haben wenig miteinander zu tun. Ein Designer sollte
sich nur in Ausnahmefällen um eine konkrete Implementierung kümmern müssen, auf
gar keinen Fall um die Vermeidung von goto und Konsorten. Ein Implementierer
hingegen kann evtl. auf einen Designfehler hinweisen. (Natürlich werden jetzt
all die supertollen Designer aufmucken, die behaupten, ein 'wasserdichtes',
unumstößliches Design vor irgendeiner Implementierung fertigstellen zu können.
Aber die kann ich sowieso nicht ernst nehmen.)

Die Verwendung von goto, breaks und continue ist nur eine Frage für den
Programmierer. Wer krampfhaft versucht, ohne sie auszukommen, tut sich und
anderen keinen Gefallen. Warum wohl haben K&R diese Sprachmittel eingeführt,
obwohl sie sehr wohl wußten, daß man prinzipiell ohne sie auskommen kann?

Die Frage ist nicht, wieviel Unfug man mit einem Sprachelement machen kann,
sondern wie nützlich es ist. Ich behaupte ebenso dogmatisch wie Erhard, daß
sogar ein goto - bewußt eingesetzt - hilfreich sein kann. Würde break und
continue aus C verbannt werden, müßte ich mich ganz schnell nach einer neuen
Sprache umschauen - und mit mir würden das Millionen anderer machen.


Ciao, Siggi.

Jan-Erik Rosinowski

unread,
Aug 14, 1996, 3:00:00 AM8/14/96
to

Moin Erhard!

JR>> p = listenanfang;
JR>> while (p && p->key != searchedkey) {
JR>> p = p->next;
JR>> }

ES> Das ist das Problem der Circuit-Evaluation.

yep, short-circuit eval und left-to-right-order

ES> Obiges kannst du ja auch in einem Struktogramm problemlos darstellen.

ich oute mich mal dahingehend, struktogramme und aehnlichen schmackofatz das
letzte mal vor 15 jahren in der schule gesehen zu haben. so mich meine
erinnerung nicht truegt, wird dort aber kein expliziter auswertungsmechanismus
a la c postuliert..

damit wird das tolle struktogramm deutlichst bescheidener und wesentlich
schwieriger zu verstehen, als obiges konstrukt..

ES> derartige Konstruktionen sind auch strukturell nirgends irgendwie
ES> unsauber, oder?

sie sind nur eher vernebelnd

ES> Nur die exit-, continue- und break-Konstruktionen sind eigentlich sehr
ES> bedenklich. Das einzige break, das in C-Programmen seine Berechtigung hat,
ES> steht in ner switch-Konstruktion (da hat es aber eher die Funktion eines
ES> end case).

deren einsatz halte ich auch fuer eher schlecht, zumal ich bei geschachtelten
konstrukten regelmaessig neu ueberlegen muss, ob ich an der gewollten stelle
ankomme. also mies wartbar

ES> Man haette das allerdings syntaktisch vielleicht eher mit { und
ES> } loesen sollen, und damit auch gleich eine weitere Fehlerquelle
ES> eliminiert, die sowieso strukturell wieder bedenklich ist.

dann koenntest du aber keine duff-devices bauen (laeuft auf manuell entrollte
schleifen hinaus), die du zu urzeiten bei miesen compilern bisweilen
brauchtest..

anders ausgedrueckt: nen chirurg wird sich auch nicht nach durchzechter nacht
mit nem skalpell rasieren :-)

Kristian Köhntopp

unread,
Aug 14, 1996, 3:00:00 AM8/14/96
to

Erhard_...@p65.f3001.n2487.z2.fidonet.org (Erhard Schwenk) writes:
>>[ 20 Jahre alter C-Code hat dieselben Strukturen wie
>> aktueller Kernel-Code ]

>Das ist IMHO eher ein Argument fuer die Betonkoepfe, die in vielen Bereichen
>der EDV heute noch sitzen und arbeiten wie vor 20 Jahren und fuer die
>Unwilligkeit (oder -faehigkeit?) vieler Informatik-Studenten, strukturierte
>Programmierung richtig zu kapieren (sonst wuerden sie gar nicht auf goto-Ideen
>kommen). Wie wollen die erst OO kapieren?

Das dieselben Leute, die Waechter-returns und Exception-goto's
in den Linux-Kernelcode schreiben auch OO verstanden haben,
habe ich ja schon an anderer Stelle in dieser Gruppe
demonstriert (die Diskussion um struct file und struct inode
und OO in C).

Du sagst, if und for seien normalisierte Formen von goto's.
Auch Waechter-Return oder SEH sind normalisierte Formen von
goto's, nur dass diese beiden speziellen Normalformen eben
nicht von Wirth stammen, sondern nach seiner Zeit formuliert
worden sind. Und genau diese Form von Code wird in
Documentation/CodingStyle ja auch formal vorgeschrieben (also
noch weiter formalisiert).

>Indentation ist IMHO das kleinere Uebel. Wenn der Quellcode sauber und nach
>festen Regeln formatiert wird, kann man das ohne Weiteres lesen.

Die Indentation ist es ja auch nicht, was Code oder solche
Kurzschluesse schwer zu lesen macht. Code ist meistens dann gut
zu lesen, wenn der normal path of execution durchgehend ist und
die Sonderfaelle auch als solche Erkennbar sind. Das ist es ja
gerade, was von

if (!vorbedingung)
return fehler;
if (!vorbedingung2)
return fehler2;

result = do_something();
if (result == subfehler)
goto cleanup;
result = do_more()
if (result == subfehler)
goto cleanup;
return result;
cleanup:
do_cleanup();
return errorcode;

gemacht wird. Jedem normalen Programmierer wird klar sein, dass
das Programm im Normalfall gerade durch diesen Code
hindurchfaellt. Wenn er sich jetzt fuer die Sonderfaelle
interessiert, kann er die Vorbedingungen und die erzeugten
Bottom-Symbole (aka Exceptions) leicht erkennen.

Und das ist auch der Modellierung leicht zugaenglich.

Uebrigens: Ein
>goto aus einer Verschachtelungsebene raus macht dem Compiler ganz erhebliche
>Schwierigkeiten, denn er muss da erstmal ermitteln, wie weit der Stack
>aufzuraeumen ist.

> K> Es waere


> K> sicherlich viel interessanter, solche Strukturen auf zu
> K> streichen und stattdessen ein typisiertes Lambda-Kalkuel
> K> anzuwenden und if durch den y-Operator und for durch
> K> endstaendige Rekursion zu ersetzen.

>Nun, Rekursion ist wohl noch bedenklicher. Du gehst in die falsche Richtung?

Nein, ich beleuchte beide Enden des Spektrums. Wir haben in der
Informatik verschiedene Berechenbarkeitsbegriffe (My-Rekursiv,
Turing-berechenbar und so weiter), die aequivalent sind. Das
eine Ende des Spektrums ist die Turingmaschine und kennt als
einzige Anweisung das goto mit Seiteneffekten. Das andere Ende
des Spektrums wird z.B. vom lambda-Kalkuel abgedeckt, das nur
Rekursion kennt und weder goto noch Seiteneffekte.

Keines dieser Extreme ist ausdruckstaerker als das andere.
Korrektheitsbeweise lassen sich mit dem einen wie mit dem
anderen fuehren. Manchmal ist der Beweis mit der einen
Darstellung einfacher als mit der anderen. Letztendlich ist es
aber schnurz.


>Der Ersatz von goto durch for und if fuehrt zu einer Spezialisierung. Was du
>machst, ist IMHO eigentlich eine Generalisierung, oder? Du schraenkst ja nicht
>ein, sondern du weitest aus.

> K> und konsequenterweise auch Variablen


> K> generell abschaffen und waere eine grossartige Vereinfachung
> K> beim Scheduling fuer symmetrische Multiprozessoren (da wir
> K> keine Seiteneffekte mehr haben, koennen wir unabhaengige
> K> Teilbaeume des Lambda-Ausdruckes leicht auf anderen Prozessoren
> K> berechnen lassen). Und weil das beweistechnisch auch viel
> K> einfacher zu handhaben ist, koennten wir den Pfad aus der
> K> Designphase in die Codierungsphase auch weitergehender
> K> automatisieren.

>Es gibt Code-Generatoren, die genau diesen Weg verfolgen. Und sie sind nicht
>die schlechtesten ;).

Ich weiss. :-) Mein Diplomvater hat so etwas in seiner eigenen
Diplomarbeit bearbeitet. Genaugenommen hat er fuer eine
Reduktionsmaschine (ein Evaluator fuer Ausdruecke im
Lambda-Kalkuel) einen Scheduler geschrieben, der
Unterausdruecke auf einem Multiprozessor (nCube mit 32
Prozessoren) auswertet.

>Von den
>Problemen von verteilter Datenhaltung und Multiuser-Umgebungen mal abgesehen.
>Schonmal ein wenig Finanzmathematik gesehen? Ich meine jetzt nicht das
>Sachrechnen aus der 10. Klasse, sondern so richtig schoene OR-Probleme.

Ich weiss. Ich habe auch OR gehoert. Trotzdem kann ich mir
wenig langweiligere Dinge vorstellen, als mit SQL-Datenbanken
und Maskengeneratoren rumzuhampeln oder NP-vollstaendige
Optimierungsprobleme zu knacken.

>[ Was ich mache ]


>Nun, da hast du das Problem doch noch viel dicker. Wie willst du in einem
>Assembler-Geraetetreiber jemals ordentlich Diagnose und Debugging betreiben
>koennen, wenn du die einfachsten Strukturregeln nicht einhaelst? Wie soll der
>Nachfolger auf deinem Arbeitsplatz jemals die sourcen warten koennen?

Wir schreiben die Geraetetreiber in C, weil der Compiler
besseren Maschinencode generiert als wir (Und ja, wir schauen
ihm auf die Finger und glauben ihm das nicht einfach so). Und
meine Kollegen koennen meine Quellen lesen, WEIL ich mich an
die boesen Mehrfachexits und Exception-gotos halte wie jeder
vernuenftige Mensch, der auf diesem Gebiet arbeitet.

Und ja, ich kann Dir eine formale Transformation angeben, die
solchen Code auf das Designmodell Deiner Wahl abbildet
(eigentlich auf den Code mit den verschachtelten if's, den Dein
Designmodell generieren wuerde, aber von da aus findest Du dann
wahrscheinlich selbst nach Hause).

> K> Nein, der ist in Ordnung. Es ist das Fido-Gateway und das
> K> Datenformat von Fido, die nicht in Ordnung sind.

>Nun, das Datenformat von Fido existiert per Definition und kann daher nicht
>falsch oder richtig sein, hoechstens sinnvoll oder sinnlos. Also wird es wohl
>das Gateway sein.

Das Datenformat von Fido ist nicht ausdrucksstark genug, um
meinen Namen korrekt und ohne Informationsverlust darstellen zu
koennen. Darum unternimmt das Gateway keinen Versuch, die
Codierung meines Namens zu wandeln, sondern schiebt den String
einfach 1:1 durch soweit es die Fido-Feldgroessen zulassen.

Der Bug liegt aber im Datenformat von Fido selbst,
genaugenommen in seiner Beschraenktheit und
Nichterweiterbarkeit.

Kristian
--
Kristian Koehntopp, Wassilystrasse 30, 24113 Kiel, +49 431 688897

"Plan:
World domination. Fast."
-- "finger torv...@linux.cs.helsinki.fi", 7. May 1996

Jan-Erik Rosinowski

unread,
Aug 15, 1996, 3:00:00 AM8/15/96
to

Moin Erhard!

ES> Uebrigens: Ein goto aus einer Verschachtelungsebene raus macht dem
ES> Compiler ganz erhebliche Schwierigkeiten, denn er muss da erstmal
ES> ermitteln, wie weit der Stack aufzuraeumen ist.

das ist ein triviales problem. die einzige echte schwierigkeit beim bau von
compilern fuer moderne sprachen (wir lassen also algol, cobol und fortran77 mal
aussen vor, die kontexabhaengig mehrdeutige grammatiken besitzen koennen),
besteht in der optimierung.

K>> sicherlich viel interessanter, solche Strukturen auf zu
K>> streichen und stattdessen ein typisiertes Lambda-Kalkuel
K>> anzuwenden und if durch den y-Operator und for durch
K>> endstaendige Rekursion zu ersetzen.

ES> Nun, Rekursion ist wohl noch bedenklicher. Du gehst in die falsche
ES> Richtung? Der Ersatz von goto durch for und if fuehrt zu einer
ES> Spezialisierung. Was du machst, ist IMHO eigentlich eine Generalisierung,
ES> oder? Du schraenkst ja nicht ein, sondern du weitest aus.

er spricht von funktionaler programmierung in ihrer reinform. da gibts auch
keine variablen im eigentlichen sinne mehr..

K>> und konsequenterweise auch Variablen
K>> generell abschaffen und waere eine grossartige Vereinfachung
K>> beim Scheduling fuer symmetrische Multiprozessoren (da wir
K>> keine Seiteneffekte mehr haben, koennen wir unabhaengige
K>> Teilbaeume des Lambda-Ausdruckes leicht auf anderen Prozessoren
K>> berechnen lassen). Und weil das beweistechnisch auch viel
K>> einfacher zu handhaben ist, koennten wir den Pfad aus der
K>> Designphase in die Codierungsphase auch weitergehender
K>> automatisieren.

ES> Es gibt Code-Generatoren, die genau diesen Weg verfolgen. Und sie sind
ES> nicht die schlechtesten ;).

stimmt, die turingmaschinen sind langsamer :-)

Enrico Thierbach

unread,
Aug 15, 1996, 3:00:00 AM8/15/96
to

Am Mo, dem 12.08.96, meinte Erhard Schwenk@2:2487/3001.65
im Area C_ECHO.GER unter goto:

MM>> Z.B setze ich mich nicht hin und zeichne irgendwelche Diagramme fuer eine
MM>> popelige Strcpy-Funktion (nur ein Beispiel). Da kommt mein Design genau
MM>> bis char *strcpy(char *ziel, const char *quelle). Und ob in einer solchen
MM>> Funktion dann irgendwo ein goto auftaucht, wird Dir spaeter nicht den

MM>> Hals brechen, glaube mir.

> Oh doch, es kann. Ich habe sowas gerade erlebt, als ein altes COBOL-Programm
> genau aus diesem Grunde 3 Tage Wartungsarbeit kostete, die sonst in 10
> Minuten erledigt gewesen waere. Ein schlichtes GOTO, das bei der Wartung
> uebersehen wurde...

da du in C ja nicht aus der funktion herausspringen kannst, wuerde ich
hier Markus recht geben...

/eno

===== PGP secure contact via E.THI...@LINK-M.DE +++ PGP key per EB =====

--- CrossPoint v3.11 R
* Origin: schneller geht's mit quantendynamischer Hypertrophie (2:2480/120.1)

Erhard Schwenk

unread,
Aug 16, 1996, 3:00:00 AM8/16/96
to

Hallo Olaf!

OG> das ist aber auch nicht das gelbe vom Ei. Dabei steht die Fehlerbehandlung
OG> mitten in der Funktion. Und die Vermischung von normaler Bearbeitung und
OG> Fehlerbehandlung steigert auch nicht die Lesbarkeit.

Wie waers denn damit, die Fehlerbehandlungen global in ne eigene Funktion zu
verfrachten? Dann steht da nur Fehler(FEHLERNUMMER) oder so. AUf die Weise
erhaelt man auch gleich ne Fehlertabelle. In Kombination mit einigen
Praeprozessor-Befehlen erhaelt man sogar recht komfortable Error- und
Panic-Meldungen. Und man kann bei Bedarf auch wieder an der Stelle
weitermachen, nachdem der Fehler beseitigt wurde.

Markus Mattes

unread,
Aug 18, 1996, 3:00:00 AM8/18/96
to

Hi Erhard,

12 Aug 96 17:40, Erhard Schwenk wrote to Markus Mattes:

MM>> Was immer noch nichts an der Tatsache aendert, dass es

MM>> Geschmacksache ist. :-) Nur weil es dann die Geschmacksache von
MM>> MEHREREN Personen ist, ist es noch lange nicht fuer den Rest der
MM>> Welt bindend.

ES> Es ist fuer das Projekt bindend. Das ist ausreichend.

Ist damit aber immer noch nicht garantiert die beste Loesung, nur weil jemand
das so zum Gesetz erhoben hat.

ES> Und es wird auch nicht immer von mehreren Personen festgelegt.

Egal von wievielen Personen festgelegt -- es ist und bleibt ein Gruppeninternes
Gesetz und hat absolut keine Berechtigung gegenueber der grossen weiten Welt.

ES> Ach ja: Und mit Geschmack hat das meist auch herzlich wenig zu tun,
ES> mehr mit Erfahrung und Verstaendnis bestimmter Techniken.

Erfahrungen eines ganz bestimmten Personenkreises mit ganz bestimmten Methoden,
in ganz bestimmten Branchen, fuer ganz bestimmte Kundenkreise.

ES>>> Das geht auch mit Papier und Bleistift. Und auch dann

ES>>> produzierst du keine GOTO's.

MM>> Kein Agree mehr. Das kommt ganz darauf an, wie tief ich mein

MM>> Design ansetze. Es kann durchaus sein, dass mein Design nur bis
MM>> zur Funktionsebene kommt.

ES> Dann ist es unvollstaendig.

Nein, dann ist es Effizient. ;-) Siehe unten, solch triviale Sachen designe ich
nicht mehr.

MM>> Z.B setze ich mich nicht hin und zeichne irgendwelche Diagramme

MM>> fuer eine popelige Strcpy-Funktion (nur ein Beispiel). Da kommt
MM>> mein Design genau bis char *strcpy(char *ziel, const char
MM>> *quelle). Und ob in einer solchen Funktion dann irgendwo ein goto
MM>> auftaucht, wird Dir spaeter nicht den Hals brechen, glaube mir.

ES> Oh doch, es kann. Ich habe sowas gerade erlebt, als ein altes
ES> COBOL-Programm genau aus diesem Grunde 3 Tage Wartungsarbeit kostete,

Du musst dazu sagen, dass dieses Programm keinerlei Kommentare, Dokumentation
und Leerzeilen enthielt, stimmt's? Ich bin mir sicher da hat es noch an ganz
anderen Sachen als nur an einem GOTO gehangen.
ES> die sonst in 10 Minuten erledigt gewesen waere. Ein schlichtes GOTO,
ES> das bei der Wartung uebersehen wurde...

Man kann nicht nur GOTOs bei der Wartung uebersehen, weisst Du? ;-)

Markus Mattes

unread,
Aug 18, 1996, 3:00:00 AM8/18/96
to

Hi Kristian,

14 Aug 96 15:52, Kristian =?ISO-8859-1?Q?K=F6hntopp? wrote to Erhard Schwenk:

[...]
Kh> Das Datenformat von Fido ist nicht ausdrucksstark genug, um
Kh> meinen Namen korrekt und ohne Informationsverlust darstellen zu
Kh> koennen.

ROTFL :-)

Erhard Schwenk

unread,
Aug 19, 1996, 3:00:00 AM8/19/96
to

Hallo Kristian!

K> Und genau diese Form von Code wird in
K> Documentation/CodingStyle ja auch formal vorgeschrieben (also
K> noch weiter formalisiert).


Also, Waechter-Returns bzw. Goto's werden in vielen Code-Richtlinien sogar
explizit verboten.

K> gemacht wird. Jedem normalen Programmierer wird klar sein, dass
K> das Programm im Normalfall gerade durch diesen Code
K> hindurchfaellt. Wenn er sich jetzt fuer die Sonderfaelle
K> interessiert, kann er die Vorbedingungen und die erzeugten
K> Bottom-Symbole (aka Exceptions) leicht erkennen.

Darum geht es nicht. Es geht z.B. darum, spaeter an genau diesen Punkten
Anweisungen einfuehren zu muessen. Und da entsteht dann schnell haessliche
Redundanz im Code, die Wartungsprobleme vervielfacht. Und es geht darum, dass
gerade solche Ausgaenge bei Wartungsarbeiten "weiter unten" im Code sehr leicht
uebersehen werden koennen.

K> Nein, ich beleuchte beide Enden des Spektrums. Wir haben in der
K> Informatik verschiedene Berechenbarkeitsbegriffe (My-Rekursiv,
K> Turing-berechenbar und so weiter), die aequivalent sind. Das
K> eine Ende des Spektrums ist die Turingmaschine und kennt als
K> einzige Anweisung das goto mit Seiteneffekten. Das andere Ende
K> des Spektrums wird z.B. vom lambda-Kalkuel abgedeckt, das nur
K> Rekursion kennt und weder goto noch Seiteneffekte.

Keines dieser beiden Enden ist aber praktikabel.

K> Keines dieser Extreme ist ausdruckstaerker als das andere.
K> Korrektheitsbeweise lassen sich mit dem einen wie mit dem
K> anderen fuehren. Manchmal ist der Beweis mit der einen
K> Darstellung einfacher als mit der anderen. Letztendlich ist es
K> aber schnurz.

Richtig. Eben deshalb ist es besser, den strukturierteren der beiden Wege zu
gehen.

K> Ich weiss. Ich habe auch OR gehoert. Trotzdem kann ich mir
K> wenig langweiligere Dinge vorstellen, als mit SQL-Datenbanken
K> und Maskengeneratoren rumzuhampeln oder NP-vollstaendige
K> Optimierungsprobleme zu knacken.

Nun ja, nicht alle finanzmathematischen Probs sind NP-vollstaendig. Abgesehen
davon, ist z.B. ne Prozessanalyse innerhalb eines solchen Grossunternehmens
manchmal hochinteressant ;).

K> Und ja, ich kann Dir eine formale Transformation angeben, die
K> solchen Code auf das Designmodell Deiner Wahl abbildet
K> (eigentlich auf den Code mit den verschachtelten if's, den Dein
K> Designmodell generieren wuerde, aber von da aus findest Du dann
K> wahrscheinlich selbst nach Hause).

Du _sollst_ das Design nicht mehr transformieren, sondern 1:1 in Code umsetzen.
Das ist der Sinn eines Designs.

Juergen Fischer

unread,
Aug 19, 1996, 3:00:00 AM8/19/96
to

Erhard Schwenk (Erhard_...@p65.f3001.n2487.z2.fidonet.org) in wrote:
> OG> das ist aber auch nicht das gelbe vom Ei. Dabei steht die
> OG> Fehlerbehandlung mitten in der Funktion. Und die Vermischung von
> OG> normaler Bearbeitung und Fehlerbehandlung steigert auch nicht die
> OG> Lesbarkeit.

> Wie waers denn damit, die Fehlerbehandlungen global in ne eigene Funktion zu
> verfrachten?

Dann hat man aber keinen Zugriff auf die lokalen Variablen und muß u.U.
erstmal auf Basis der lokalen Variablen eine Fehlernummer berechnen. Dann
kann man sich's gleich sparen...


Jürgen
--
Juergen Fischer internet: fis...@et-inf.fho-emden.de voice: +49-4931-168199

Schulstrasse 18 fidonet: fischer@2:2426/1010.14 fax/data: +49-4931-168194
D-26506 Norden
Unix - where do you want to fly today? / why "go" with a pair of wings

--- FIDOGATE 4.0alpha2
* Origin: Unix-Site under construction (2:2426/1010.14)

Erhard Schwenk

unread,
Aug 19, 1996, 3:00:00 AM8/19/96
to

Hallo Jan-Erik!

JR> ich oute mich mal dahingehend, struktogramme und aehnlichen schmackofatz
JR> das letzte mal vor 15 jahren in der schule gesehen zu haben.

Nun ja, es gibt ja auch noch andere Design-Methoden. Struktogramme sind
allerdings wohl am weitesten verbreitet (neben Pseudo-Code). Wobei aber jetzt
nicht gesagt ist, dass das Design nur aus Struktogrammen besteht. Die sind nur
eine der letzten Stufen.

JR> so mich meine
JR> erinnerung nicht truegt, wird dort aber kein expliziter
JR> auswertungsmechanismus a la c postuliert..

JR> damit wird das tolle struktogramm deutlichst bescheidener und wesentlich
JR> schwieriger zu verstehen, als obiges konstrukt..

Falsch, es wird einfacher, weil solche Effekte wie sie durch deine Logik
entstehen dort gar nicht beruecksichtigt werden muessen. Im Struktogramm geht
wes ja zunaechst auch gar nicht darum, sondern man will erstmal die Logik des
Programms an sich festklopfen. Was da in welcher Reihenfolge ausgewertet werden
muss, ist in dem speziellen Fall von sekundaerem Interesse.

JR> dann koenntest du aber keine duff-devices bauen (laeuft auf manuell
JR> entrollte schleifen hinaus), die du zu urzeiten bei miesen compilern
JR> bisweilen brauchtest..

Das duerfte sich inzwischen wohl erledigt haben.

JR> anders ausgedrueckt: nen chirurg wird sich auch nicht nach durchzechter
JR> nacht mit nem skalpell rasieren :-)

Nee, er wird wohl erstmal ein paar Blinddaerme rausnehmen, um die
Geschicklichkeit zu testen ;).

Erhard Schwenk

unread,
Aug 22, 1996, 3:00:00 AM8/22/96
to

Hallo Juergen!

JF> Dann hat man aber keinen Zugriff auf die lokalen Variablen und muß u.U.
JF> erstmal auf Basis der lokalen Variablen eine Fehlernummer berechnen. Dann
JF> kann man sich's gleich sparen...

Die Fehlernummer kann ich mitgeben. Ich mach sowas mit ner Kombination aus
Praeproz-#defines und Funktionen und krieg dann einfach ne Meldung mit
Fehlernummer, Modul- und Funktionsname und kurzer Fehlerbeschreibung, eventuell
auch noch Inhalte von lokalen Variablen (bei C++ problemlos machbar, in C nur
ueber void-Zeiger und Steuerstrings fuer printf()). und danach kann ich
entweder wieder da aufsetzen wo ich war oder das Programm beenden. Das gilt
natuerlich nur fuer fatale Fehler, die ein Weiterlaufen des Prgs sinnlos
machen. Aber auch da ist kein break oder continue oder goto von der Partie -
hoechstens ein einzelnes exit() am Ende der Auswertefunktion fuer die
Fehlermeldungen, aber das versuche ich auch moeglichst zu vermeiden.

Siegfried Weiss

unread,
Aug 26, 1996, 3:00:00 AM8/26/96
to

Hi Erhard,

ES> Aber auch da ist kein break oder continue oder goto von der Partie -
ES> hoechstens ein einzelnes exit() am Ende der Auswertefunktion fuer die
ES> Fehlermeldungen, aber das versuche ich auch moeglichst zu vermeiden.

und warum vermeidest Du exit() nicht grundsätzlich, ist doch machbar :-))


Ciao, Siggi.

Jan-Erik Rosinowski

unread,
Aug 30, 1996, 3:00:00 AM8/30/96
to

Moin Erhard!

JR>> wird dort aber kein expliziter auswertungsmechanismus a la c postuliert..

JR>> damit wird das tolle struktogramm deutlichst bescheidener und

JR>> wesentlich schwieriger zu verstehen, als obiges konstrukt..

ES> Falsch, es wird einfacher, weil solche Effekte wie sie durch deine Logik
ES> entstehen dort gar nicht beruecksichtigt werden muessen. Im Struktogramm

also zurueck zum beispiel:

p=listenanfang;
while (p && p->data != searchval) p = p->next;

ausgangspunkt meiner argumentation war, dass sprachen wie pascal eine
standardisierte short-circuit-evalualtion nicht kennen und somit bisweilen
obfuscated code erzwingen (es darf hier nicht auf p-> zugegriffen werden, wenn
p=0 gilt und os!=junk). deine standardantwort 'mit tollen designmethoden ist
das alles kein problem' sticht leider nicht fuer fuenf pfennig bzw verkehrt
sich ins gegenteil, da just eine s-c-evaluation nicht postuliert wird und der
code sich somit verkompliziert.

ES> Logik des Programms an sich festklopfen. Was da in welcher Reihenfolge
ES> ausgewertet werden muss, ist in dem speziellen Fall von sekundaerem
ES> Interesse.

positively no

Erhard Schwenk

unread,
Aug 31, 1996, 3:00:00 AM8/31/96
to

Hallo Siegfried!

SW> Hi Erhard,

ES>> Aber auch da ist kein break oder continue oder goto von der Partie -
ES>> hoechstens ein einzelnes exit() am Ende der Auswertefunktion fuer die
ES>> Fehlermeldungen, aber das versuche ich auch moeglichst zu vermeiden.

SW> und warum vermeidest Du exit() nicht grundsaetzlich, ist doch machbar :-))

Ist natuerlich machbar (und wird auch nach Moeglichkeit gemacht). Nur eine
Frage des gewuenschten Aufwandes - das Programm besteht dann halt aus einer
Verschachtelungsebene mehr, die in fast jeder Funktion auftritt. Aber bei
Q&D-Hacks kann sowas recht schnell nerven, und dann nimmt man halt doch wieder
exit(). Aber Designmaessig ist das natuerlich unsauber.

Erhard Schwenk

unread,
Sep 2, 1996, 3:00:00 AM9/2/96
to

Hallo Jan-Erik!

JR> also zurueck zum beispiel:

JR> p=listenanfang;
JR> while (p && p->data != searchval) p = p->next;

JR> ausgangspunkt meiner argumentation war, dass sprachen wie pascal eine
JR> standardisierte short-circuit-evalualtion nicht kennen und somit bisweilen
JR> obfuscated code erzwingen (es darf hier nicht auf p-> zugegriffen werden,
JR> wenn p=0 gilt und os!=junk). deine standardantwort 'mit tollen
JR> designmethoden ist das alles kein problem' sticht leider nicht fuer fuenf
JR> pfennig bzw verkehrt sich ins gegenteil, da just eine s-c-evaluation nicht
JR> postuliert wird und der code sich somit verkompliziert.

Darum geht es ja beim Design auch nicht. Das was du zeigst, ist ein reines
Implementierungsproblem. Designmaessig ist der Ausdruck (der in dieser Form gar
nicht im Struktogramm stehen kann, da dasselbe ja Sprach- und Systemunabhaengig
sein soll, da steht dann sowas wie "Treffer oder keine weiteren Elemente mehr
vorhanden?" drin) im Prinzip zulaessig. Wenn eine Sprache das nicht
implementieren kann, ist das ein sprachspezifisches (wenn auch sehr
verbreitetes) Problem, fuer das im Allgemeinen ein Standard-Loesungsverfahren
existiert. Dafuer ist dann tatsaechlich die "Codier-Sau" zustaendig. Der
Designer kuemmert sich genau um solche Dinge nicht.

Andererseits darf aber natuerlich der Codierer nichts anderes implementieren,
als im Design vorgeschrieben wird. Das heisst, wenn etwa das Design als
unterste Ebene aus Struktogrammen und ER-Diagrammen besteht, hat er sich an die
dort beschriebenen Ablaeufe und Definitionen zu halten, was im Allgemeinen
problemlos moeglich ist. Fuer jede der 4 Struktogrammstrukturen (Sequenz,
Schleife, Entscheidung, Unter-Block) gibt es in jeder prozeduralen Sprache
geeignete Standard-Implementierungsverfahren. Das muss nicht unbedingt heissen,
dass ein Struktogramm-Block nur einen Befehl erzeugen darf, aber es heisst,
dass die Struktur des Designs sich im Code wiederfinden muss. So kann z.B. in
COBOL-74 (heute kaum noch verbreitet) If-Bloecke nicht richtig verschachteln.
Hier gibt es aber 2 Standard-Verfahren (Auslagern in einen PERFORM-Block oder
herausnehmen des inneren IF und Verknuepfen der Bedingungen mit AND) zur
Implementierung, die z.B. auch in Codier-Richtlinien verbrieft sein koennen.
Aehnliches gilt fuer das Problem der short-circuit-evaluation. Aber das aendert
nichts an der Tatsache, dass ein Implementierungs- und kein Design-Problem
vorliegt.

Jan-Erik Rosinowski

unread,
Sep 8, 1996, 3:00:00 AM9/8/96
to

Moin Erhard!

ES> ein Standard-Loesungsverfahren existiert. Dafuer ist dann
tatsaechlich die
ES> "Codier-Sau" zustaendig. Der Designer kuemmert sich genau um solche
Dinge
ES> nicht.

dann frage ich mich allerdings, wozu ein designer sich ueberhaupt auf
dieses
niveau begeben sollte..

nassi-schneidermann & co. taugt imho allenfalls fuer den
informatikunterricht,
da sich sonst 2 leute ueber das gleiche problem gedanken machen muessen,
wobei
die arbeit des designers nett, aber fuer die ablage ist.

er-modellierung sehe ich durchaus als sinnvoll an, aber wo "design" den
codierungsprozess betrifft und nicht automatisch ohne jegliche handarbeit
in
die zielsprache transformiert werden kann, wird imho bestenfalls
ueberfluessiger kaese spezifiziert.

wenn ich auftraege an dritte uebergebe, ist das unterste niveau die
vorgabe des
headerfiles. wenn ich weiss, dass die leute was koennen geschieht aber
auch das
nur auf informeller basis bzw wir reden ueber die spezifikation des
gesamtsystems.

alles andere ist imho...

Erhard Schwenk

unread,
Sep 13, 1996, 3:00:00 AM9/13/96
to

Hallo Jan-Erik!

ES>> ein Standard-Loesungsverfahren existiert. Dafuer ist dann
tatsaechlich
die
ES>> "Codier-Sau" zustaendig. Der Designer kuemmert sich genau um solche
Dinge
ES>> nicht.

JR> dann frage ich mich allerdings, wozu ein designer sich ueberhaupt auf
JR> dieses niveau begeben sollte..

Soll er ja auch nicht. Das Nassi-Shneidermann-Diagramm ist fuer den
Designer
da, und auf der Ebene haben solche Dinge eigentlich nix zu suchen. Wie ein
solches implementiert wird, interessiert ihn nicht, denn er soll ja gerade
moeglichst unabhaengig vom System oder den Werkzeugen arbeiten.

JR> nassi-schneidermann & co. taugt imho allenfalls fuer den
JR> informatikunterricht, da sich sonst 2 leute ueber das gleiche problem
JR> gedanken machen muessen, wobei die arbeit des designers nett, aber
fuer
JR> die ablage ist.

Du hast noch nie in nem grossen Projekt mitgearbeitet? Die Programmierung
selbst ist bei richtig grossen Projekten ungefaehr 20% der eigentlichen
Arbeit.
Die restlichen 80% der Zeit und des Etats werden im Allgemeinen fuer
Analyse
und Design verbraten. Und das macht durchaus Sinn. Es ist der einzige
bekannte
Weg, um mit grosser Wahrscheinlichkeit ueberhaupt funktionierende und den
Anforderungen entsprechende Programme zu erhalten. Und es erhoeht die
Wartbarkeit ungemein. Und die Arbeit des Designers ist auch nicht fuer die
Tonne, sondern stellt 2/3 der Code-Dokumentation dar, auf die du wenn du
das
Programm in 10 Jahren mal aendern willst, dringend angewiesen bist.

JR> er-modellierung sehe ich durchaus als sinnvoll an, aber wo "design"
den
JR> codierungsprozess betrifft und nicht automatisch ohne jegliche
handarbeit
JR> in die zielsprache transformiert werden kann, wird imho bestenfalls
JR> ueberfluessiger kaese spezifiziert.

Nein. Das Design interessiert sich ueberhaupt nicht fuer irgendeine
Zielsprache. Es ist Aufgabe des Codierers, die im Design vorhandenen
Konstrukte
(bei prozeduralen Sprachen eigentlich nur Sequenz, if, While und Block) in
die
jeweilige Programmiersprache umzusetzen. Bei COBOL kannst du zum Beispiel
WHILE-Schleifen nur bedingt umsetzen, insbesondere wenn sie Fussgesteuert
sind,
und auch IF-Verschachtelungen haben z.B. in COBOL-74 (was durchaus bei
vielen
Betrieben noch im Einsatz ist!) gewisse Grenzen. Diese Aufgaben uebernimmt
der
Codierer. Sie aendern auch nichts am Design oder an der Funktion des
Programms,
und meist gibt es Standardisierte Verfahren fuer die Umsetzung.

Eine saubere Entwicklung besteht zunaechst aus einer Anforderungs-Analyse
(es
wird schriftlich fixiert, was das Programm ueberhaupt machen soll,
teilweise
auch durch echte Prozessanalysen mittels SA oder SADT), der eine
Design-Phase
folgt. Diese beinhaltet die Erstellung eines Datenmodells (ER-Modell, Data
Dictionary), einer statischen (Jackson, ergibt Funktionenbaum) und
dynamischen
(SA oder SADT, also DFD's und Nassi-Shneidermann, kann aus der
Analyse-Phase
abgeleitet werden) Funktionsmodellierung und einer ausfuehrlichen
Funktionsbeschreibung sowie eventuell (heute dank moderner Werkzeuge
eigentlich
meistens) ersten Rapid-Prototypes. Dieses Design wird anschliessend
bereits
getestet (dafuer gibts spezielle Tools), und erst wenn die Verifikation
des
Designs erfolgreich verlief, wird Code produziert. Und das alles hat
durchaus
seine Berechtigung. Bei der Codierung kommt dann noch das Code-Handbuch
und ein
Variablen- und Funktionsverzeichnis hinzu. Erst dann ist ein Projekt
sauber
abgearbeitet.

JR> wenn ich auftraege an dritte uebergebe, ist das unterste niveau die
vorgabe
JR> des headerfiles. wenn ich weiss, dass die leute was koennen geschieht
aber
JR> auch das nur auf informeller basis bzw wir reden ueber die
spezifikation
JR> des gesamtsystems.

Dann hast du bei der Wartung des Codes irgendwann ein Problem. Einen
Source
ohne Design und Doku wuerde ich dir als Betrieb, der die naechsten 20-30
Jahre
mit der Software arbeiten muss (so lang lebt Software wirklich!), niemals
abkaufen. Da ist mir mein Hals zu schade dafuer.

0 new messages