#include <stdio.h>
void main( void )
{
int i = 0;
for (;;)
printf("Wert : %i\n",i++);
}
(Hintergrund war einmal herauszufinden, wie sich Linux verhaelt, wenn davon in
jeder der virtuellen Konsolen eine Kopie laeuft.)
Uebersetzt wurde mit gcc -o test test.c -Wall
Ich erhalte keine Warnings pp. (Ok ich weiss das das Programm keinen
definierten Abbruch enthaelt) aber es laeuft nicht. Nach dem Aufruf lande ich
sofort (ohne Ausgabe wie erwartet, aber auch keine Fehlermeldung) wieder in der
Kommandozeile. Ein als Gegentest geschriebenes Hello-World funktioniert wie
erwartet und auch die Uebersetzung des o.g. Codes mit EMX-GCC unter OS/2
bereitet (wie erwartet) keine Probleme.
Eine Uebersetzung mit der Option -g und ein Aufruf ueber GDB, dann funktioniert
das "Prograemmchen" komischerweise. So und jetzt bin ich einigermassen ratlos
(ach so dass printf als INT printf(..) deklariert ist weiss ich, aendert aber
auch nichts)
LINUX-4U(Unifix) Kernel 1.2.13
GCC 2.7.0
SHELL ist BASH
ciao Peter
--- Yuppie! v2.12
* Origin: POINT # 91 @ K&S Mailbox Aachen (2:2452/117.91)
PM>Uebersetzt wurde mit gcc -o test test.c -Wall
PM>aber es laeuft nicht.
Entweder starte es mit './test' oder Übersetze es z.B. mit
'gcc -o mytest test.c -Wall'. Erklärung: es gibt bereits sowohl ein
/usr/bin/test als auch als internes Shell-Komando unter diesem Namen. Mach' Dir
nix draus, da sind wohl die meisten UNIX-Einsteiger mal drüber gestolpert 8-)).
Tschö, Jojo
Mails > _64k_ -> SCHMITZ...@Tandem.COM
>Uebersetzt wurde mit gcc -o test test.c -Wall
>Ich erhalte keine Warnings pp. (Ok ich weiss das das Programm keinen
>definierten Abbruch enthaelt) aber es laeuft nicht. Nach dem Aufruf lande ich
>sofort (ohne Ausgabe wie erwartet, aber auch keine Fehlermeldung) wieder in
der
>Kommandozeile.
:-)
Versuch mal Dein Programm mit vollständiger Pathangabe aufzurufen.
Grund:
Es gibt ein Programm namens test, und es sieht so aus, als ob dieses
statt Deinem Programm aufgefufen hast (Environmentvariable PATH !!!)..
Dein Programm an sich läuft.
Gruß
Jörg
Die for-Anweisung erwartet drei Ausdrücke, von denen Du keinen einzigen
definiert hast. Der zweite Ausdruck beinhaltet die Schleifenbedingung. Da kein
Ausdruck definiert wurde, nehme ich an, daß unter anderem auch der Ausdruck für
die Schleifenbedingung vom aktuellen Inhalt des Akkus bestimmt wird.
Ohne Optimierung wird der Compiler zuerst i mit 0 initialisieren. Die
Schleifenbedingung ist damit immer FALSE.
Mit Optimierung könnte es sein, daß der Compiler i erst später oder gar nicht
initialisiert. Der Akku enthält dann irgendeinen Wert. Ist die
Schleifenbedingung erfüllt, könnte es sein, daß beim Überlauf von i ein Abbruch
stattfindet. Ansonsten läuft die Schleife endlos.
Hattest Du vielleicht folgendes gewollt?
int i;
for( i=0; i<1000; i++ )
printf( "Wert : %d", i );
oder gar eine Endlosschleife?
int i;
for( i=0; TRUE; i++ )
printf( "Wert : %d", i );
PM>Uebersetzt wurde mit gcc -o test test.c -Wall
[Kicher!]
Der typische Fehler für einen Linux-Anfänger :) (ist mir auch passiert): Es
gibt ein Tool namens test, mit dem man z.B. die Existenz einer Datei bzw. ihre
Art überprüfen kann. Wenn Du jetzt test eingibst, wird das test in /usr/bin
(bzw. /bin, ich weiß jetzt nicht, wo das liegt) ausgeführt, welches sofort
terminiert (guck Dir mal die man-page von test an).
Möchtest Du "Dein" test starten, so mußt Du nur ./test eingeben, den Pfad also
direkt mit angeben.
cu
Torsten
> Uebersetzt wurde mit gcc -o test test.c -Wall
:)))
ich glaube, den Fehler macht jeder einmal.
Es gibt unter Linux bereits ein Programm, das test heißt. Was es genau
tut, weiß ich nicht, aber es wird dank der Suchreihenfolge von Unix
aufgerufen und nicht dein eigenes test.
Ciao
Sönke
"My homepage is my castle"
TL> Wenn Du jetzt test eingibst, wird das test in /usr/bin (bzw. /bin, ich weiß
jetzt nicht, wo das liegt) ausgeführt, welches sofort terminiert (guck Dir mal
die man-page von test an).
Wir hatten uns deshalb an der Uni darauf geeinigt, unsere 'test'-Programme
immer mit 'Kotz' oder 'Sch...' zu bezeichnen. So was steht bestimmt nicht in
/bin, /etc oder /usr. Außerdem haben wir die Erfahrung gemacht, daß unsere
Testprogramme dann auch besser liefen.
Ciao, Siggi.
Es war doch schon recht spät, als Du Mitte letzter Woche wegen gcc
/LINUX-Problem folgende Zeilen geschrieben hast:
P.M> Uebersetzt wurde mit gcc -o test test.c -Wall
Hihi. Das ist einer der lustigsten UNIX-Witze überhaupt. :-)
Passiert wohl jedem am Anfang mindestens einmal - manchen auch öfter.
'test' ist ein Shellkommando, d.h. beim Aufruf von 'test' startet die Shell
gar nicht Dein Programm, sondern testet irgendwas, was sie dann über den
EXITCODE zurückmeldet.
Und damit man so richtig schön lange verzweifelt sucht, macht test _keine_
Ausgabe auf die Konsole.
Hoffe geholfen zu haben.
_ Schönen Tag noch
) _ _
(\(-)(_(-
Diese Mail enthält sage und schreibe 6 mal das Wort 'test'!
--- PGP-key avail via ConfRcptReq!
* Origin: Vom Window verweht (2:2480/412.77)
PM>> void main( void )
PM>> {
PM>> int i = 0;
PM>>
PM>> for (;;)
PM>> printf("Wert : %i\n",i++);
PM>> }
> Ich weiß nicht, was Du unter bei diesem Programm funktionieren verstehst,
> für mich ist jedenfalls nicht vorhersehbar, was das Programm überhaupt
> macht. Ich würde mal sagen, das ist ein Beispiel, wie man logischen Unsinn
> dem Compiler syntaktisch richtig unterjubeln kann :-).
Das ist eine Endlosschleife. Unter DOSen oder unter Windoof ist soetwas
absolut tötlich, aber unter einem richtigen Betriebssystem (und linux ist
zweifellos ein richtiges Betriebssystem) stellen solche Programme
überhaupt kein Problem dar.
> Die for-Anweisung erwartet drei Ausdrücke, von denen Du keinen einzigen
> definiert hast.
Die for-Anweisung erwartet _nicht_ drei Ausdrücke. Die for-Anweisung
braucht (wie hier) keinen einzigen Ausdruck enthalten, kann aber auch
meinetwegen fünf enthalten:
for ( i=0,j=14; i<100; i++,j*=5 ) ...
> Der zweite Ausdruck beinhaltet die Schleifenbedingung. Da
> kein Ausdruck definiert wurde, nehme ich an, daß unter anderem auch der
> Ausdruck für die Schleifenbedingung vom aktuellen Inhalt des Akkus bestimmt
> wird.
Nein. Abgesehen davon, daß nicht alle Linux-Systeme einen "Akku" besitzen,
ist deine Annahme falsch.
> Ohne Optimierung wird der Compiler zuerst i mit 0 initialisieren.
Auch mit Optimierung. Der Autor hat schließlich
int i = 0;
vor dem Start der Schleife geschrieben.
> Die Schleifenbedingung ist damit immer FALSE.
Nein, sie ist nicht _damit_ immer 0 (FALSE gibt es nicht in C), sie _ist_
immer 0, eben weil sie fehlt.
> Mit Optimierung könnte es sein, daß der Compiler i erst später oder gar
> nicht initialisiert. Der Akku enthält dann irgendeinen Wert.
Was ist mit dir los? Du läßt doch sonst nicht soviel Müll ab.
Die Variable i ist initialisiert!
> Ist die Schleifenbedingung erfüllt, könnte es sein, daß beim Überlauf
> von i ein Abbruch stattfindet.
Es findet in C niemals ein Abbruch bei Überlauf von Integern statt.
> Ansonsten läuft die Schleife endlos.
Sie tut es (und wenn Du die Ursprungsmail aufmerksamer gelesen hättest,
wüsstest Du, daß das so gewollt war).
ROTFL!!
cu
Torsten
bricht ab, wenn i einmal seinen Wertebereich durchlaufen hat und auf 0
kommt, oder bin ich da völlig C-unwissend? (Falls dem so ist, verratet
es nicht meinem Brötchengeber :-)
- Marcus
*** Am Samstag 08. Juni 1996 um 10:15 schrieb Siegmund Schreiber%R an
Peter
Marbaise:
SSR> Die for-Anweisung erwartet drei Ausdruecke, von denen Du keinen
einzigen
SSR> definiert hast.
Du solltest Dich mal informieren, wie "for()" verwendet wird, bevor Du so
etwas
hier ablaesst. Jeder der drei Ausdruecke einer for-Schleife _kann_
weggelassen
werden, auch 2 von 3 oder alle 3.
SSR> nicht initialisiert. Der Akku enthaelt dann irgendeinen Wert. Ist
die
bla bla. C kennt keinen "Akku".
SSR> oder gar eine Endlosschleife?
for (;;) ist erst mal eine Endlosschleife, wenn break im Innern nicht
verwendet
wird.
Tschau...Thomas
--- E3-32/1.11-32/2.50+
* Origin: Die TeX-Box +49-6034-1455 V.34 -930022 ISDN 24h (2:244/1130.42)
08 Jun 96 10:15, Siegmund Schreiber%R wrote to Peter Marbaise:
[...]
PM>> int i = 0;
PM>> for (;;)
[...]
SR> Die for-Anweisung erwartet drei Ausdruecke, von denen Du keinen
SR> einzigen definiert hast.
Macht nix.
6.6.5.3 The for statement
[...]
for ( expression-1 ; expression-2 ; expression-3) statement
[...]
Both expression-1 and expression-3 may be omitted. Each is evaluated as a
void
expression. An omitted expression-2 is replaced by a nonzero constant.
SR> Der zweite Ausdruck beinhaltet die
SR> Schleifenbedingung. Da kein Ausdruck definiert wurde, nehme ich an,
SR> dass unter anderem auch der Ausdruck fuer die Schleifenbedingung vom
SR> aktuellen Inhalt des Akkus bestimmt wird.
Siehe oben. Wenn die Abbruchsbedingung weggelassen wird, kann man sich
darauf
verlassen, dass sie durch eine Konstante != 0 ersetzt wird, was bedeutet,
das
die Schleife von sich aus nie abbricht, da eine Konstante != 0 immer zu
TRUE
evaluiert.
SR> Ohne Optimierung wird der Compiler zuerst i mit 0 initialisieren.
SR> Die Schleifenbedingung ist damit immer FALSE.
Die Schleife ohne alle Ausdruecke ist identisch mit "while(c) statement"
wobei
c immer eine Konstante != 0 ist. Sie ist dadurch also immer TRUE.
SR> Mit Optimierung koennte es sein, dass der Compiler i erst spaeter
SR> oder gar nicht initialisiert.
Nope. Wenn das passiert, dann schmeiss den Compiler weg. ;-)
SR> Der Akku enthaelt dann
SR> irgendeinen Wert. Ist die Schleifenbedingung erfuellt, koennte es
SR> sein, dass beim Ueberlauf von i ein Abbruch stattfindet. Ansonsten
SR> laeuft die Schleife endlos.
Die Schleife laeuft, wenn expression-2 weggelassen wurde, IMMER endlos (es
sei
denn sie wird durch ein explizites break verlassen). Das ist im Standard
so
festgelegt.
SR> for( i=0; TRUE; i++ )
oder for(i=0; ;i++)
ByE/2,
MarKus.
--- (c) Frobozz Magic Tearline Company
* Origin: xxx (2:2454/505.69)
> >Es findet in C niemals ein Abbruch bei Überlauf von Integern statt.
> int i=1;
> for (;i;i++);
>
> bricht ab, wenn i einmal seinen Wertebereich durchlaufen hat und auf 0
> kommt, oder bin ich da völlig C-unwissend?
der Topic war
int i=0;
for(;;) {
...
i++;
}
Es ging also um Abbruch durch Überlauf per Runtime-Fehler und jener findet
in C nicht statt!
SML>Nein, sie ist nicht _damit_ immer 0 (FALSE gibt es nicht in C), sie
SML>_ist_ immer 0, eben weil sie fehlt.
Ist ja schon gut, dann eben nicht FALSE sondern NULL...
SML>Was ist mit dir los? Du läßt doch sonst nicht soviel Müll ab.
SML>Die Variable i ist initialisiert!
> Ist die Schleifenbedingung erfüllt, könnte es sein, daß beim Überlauf
>von i ein Abbruch stattfindet.
SML>Es findet in C niemals ein Abbruch bei Überlauf von Integern statt.
Mein Denkfehler war, daß ich nicht berücksichtigt hatte, daß der zweite
Ausdruck optional ist. Ich war davon ausgegangen, daß dieser immer
ausgewertet wird, im schlimmsten Fall also durch den aktuellen letzte
Ausdruckn (in der Regel der Akku und damit evtl. der Inhalt von i). Wenn
Du diese Annahme zugrundelegst, werden Dir meine Überlegungen vielleicht
klarer. Trotzdem sind sie aber natürlich falsch. Ich hab nochmal
nachgelesen:
Fehlt der zweite Ausdruck, so wird die for-Anweisung zu einer unendlichen
Schleife.
Sorry für meinen Müll...
Keine Angst, Du hast schon Recht :-)
Aber im diskutierten Beispiel war die Schleife ja:
int i=0;
for (;;i++ );
SML>> Die Schleifenbedingung ist damit immer FALSE.
SML>
SML>Nein, sie ist nicht _damit_ immer 0 (FALSE gibt es nicht in C), sie
_ist_
SML>immer 0, eben weil sie fehlt.
SML>
Kleine Korrektur:
Sie ist immer *ungleich* 0.
greetings
Morus
MO> >Es findet in C niemals ein Abbruch bei Überlauf von Integern statt.
MO> int i=1;
MO> for (;i;i++);
MO> bricht ab, wenn i einmal seinen Wertebereich durchlaufen hat und auf 0
MO> kommt, oder bin ich da völlig C-unwissend? (Falls dem so ist, verratet
MO> es nicht meinem Brötchengeber :-)
Gemeint war ein Abbruch durch den Überlauf, nicht durch das Testen auf 0!
Ein Abbruch durch Überlauf wird z.B. in Sprachen wie Modula-2 erzeugt.
Beispiel:
C Modula-2
#include <limits.h> MODULE test;
#include <stdlib.h>
unsigned i; VAR i : CARDINAL;
int main(void) { BEGIN
i = UINT_MAX; i := MAX(CARDINAL);
++i; /* :-) */ INC( i ); (* :-( *)
return EXIT_SUCCESS; END test.
}
Im obigen Beispiel wird der Modula-2 Pendant des C Programms durch
einen Laufzeitfehler (natürlich nur, wenn die Erzeugung solcher zur
Übersetzungszeit des Programms eingeschaltet war) abgebrochen (Der
Exitcode wird != 0 sein).
Das C Programm hingegen wird normal terminieren (Exitcode == 0).
Dies ist etwas völlig anderes als Dein Beispiel, in welchem Du das
Programm nicht durch den Überlauf, sondern anschließend durch den
expliziten Test auf 0 terminieren läßt.
Zur Erläuterung: Dein Beispiel ließe sich z.B. auch so implementieren
(wieder sowohl C als auch Modula-2):
C Modula-2
#include <stdlib.h> MODULE test2;
int i; VAR i : INTEGER;
int main( void ) { BEGIN
i = 1; i := 1;
while( i ) /* (a) */ WHILE i # 0 DO (* (a) *)
++i; /* (b) */ INC( i ) (* (b) *)
return EXIT_SUCCESS; END
} END test2.
Das Modula-2 Programm wird durch einen (Arithmetik-Überlauf) Laufzeit-
fehler abgebrochen (zum Zeitpunkt (b)), während das C-Programm korrekt
durch die Schleifenbedingung (zum Zeitpunkt (a)) beendet wird.
Fazit:
1. Die beiden Programme sehen zwar gleich aus, tun aber nicht das Gleiche!
2. In C findet niemals ein abnormaler (davon war hier die Rede) Abbruch
eines Programmes durch Arithmetik-Überlauf statt.
3. Ich hoffe, daß Dein Brötchengeber hier nicht mitließt ,-)
€iao,
Torsten
SS>Die for-Anweisung erwartet drei Ausdrücke, von denen Du keinen einzigen
SS>definiert hast. Der zweite Ausdruck beinhaltet die Schleifenbedingung.
Da kein
SS>Ausdruck definiert wurde, nehme ich an, daß unter anderem auch der
Ausdruck für
SS>die Schleifenbedingung vom aktuellen Inhalt des Akkus bestimmt wird.
SS>Ohne Optimierung wird der Compiler zuerst i mit 0 initialisieren. Die
SS>Schleifenbedingung ist damit immer FALSE.
SS>Mit Optimierung könnte es sein, daß der Compiler i erst später oder gar
nicht
SS>initialisiert. Der Akku enthält dann irgendeinen Wert. Ist die
SS>Schleifenbedingung erfüllt, könnte es sein, daß beim Überlauf von i ein
Abbruch
SS>stattfindet. Ansonsten läuft die Schleife endlos.
SS>
Hä? for (;;) ist eine Endlosschleife und muß auch immer so laufen.
Das ist so definiert! Wenn keine Abbruchbedingung angegeben ist, so ist
sie TRUE. (Oder um Kernighan zu zitieren (A.9.5): ... Fehlt der mittlere
Ausdruck, ist der implizierte Test äquivalent zum Test einer von 0
verschiedenen Konstanten)
Das Programm gibt unendlich lange Zeilen der Form "Wert: <Zahl>" aus,
wobei Zahl von 0 hochgezaehlt wird. Daß Zahl irgendwann überläuft
ist natuerlich richtig...
greetings
Morus
SML> Die for-Anweisung erwartet _nicht_ drei Ausdrücke. Die for-Anweisung
SML> braucht (wie hier) keinen einzigen Ausdruck enthalten, kann aber auch
SML> meinetwegen fünf enthalten:
SML>
SML> for ( i=0,j=14; i<100; i++,j*=5 ) ...
\__ __/ \_ _/ \__ __/
1 2 3
Dies sind nur 3 Ausdrücke!!!!!
cu,
Torsten
am 08.06.96 10:15 erzähltest Du Peter
PM>>Hallo, als absoluter Linux-Neuling habe ich nur so zum Spass folgendes
PM>> Prograemmchen uebersetzt: #include <stdio.h> void main( void ) {
int
PM>> i = 0; for (;;) printf("Wert : %i\n",i++); }
SS> Ich weiss nicht, was Du unter bei diesem Programm funktionieren
SS> verstehst, fuer mich ist jedenfalls nicht vorhersehbar, was das
SS> Programm ueberhaupt macht.
für Dich. :-)
SS> Die for-Anweisung erwartet drei Ausdruecke, von denen Du keinen
SS> einzigen definiert hast. Der zweite Ausdruck beinhaltet die
SS> Schleifenbedingung. Da kein Ausdruck definiert wurde, nehme ich an,
SS> dass unter anderem auch der Ausdruck fuer die Schleifenbedingung vom
SS> aktuellen Inhalt des Akkus bestimmt wird.
Da liegst Du kräftig daneben.
SS> Ohne Optimierung wird der Compiler zuerst i mit 0 initialisieren.
steht doch da. :-)
SS> Die Schleifenbedingung ist damit immer FALSE.
Da keine angegeben ist, ist sie *immer TRUE*.
SS> Mit Optimierung koennte es sein, dass der Compiler i erst spaeter
oder
SS> gar nicht initialisiert.
i ist doch explizit initialisiert.
SS> Der Akku enthaelt dann irgendeinen Wert.
was hat der Accu damit zu tun?
SS> Ist die Schleifenbedingung erfuellt, koennte es sein, dass beim
SS> Ueberlauf von i ein Abbruch stattfindet. Ansonsten laeuft die
Schleife
SS> endlos.
for (;;)
hat keine Initialisierung,
keine Abbruchbedingung, also immer TRUE
und ist damit identisch mit: while (1)
Guck noch mal in Deinen K&R und staune!
In C ist auch das völlig legal:
for(i = 4711; *p++; z +=3, i = f(i - 7));
Eine for-Schleife *ohne* Rumpf!
Tschau/Bye
Herbert email: h...@softpro.de
Member #53 of Team/OS2 Germany
--- Sqed/32 1.11a/r00196
* Origin: Schont die Umwelt: Vermeidet DOSen (2:2476/493)
Hallo Siegmund,
SSrmd> Die for-Anweisung erwartet drei Ausdruecke, von denen Du keinen
SSrmd> einzigen definiert hast.
Noe.
#define FOREVER() for(;;)
Von welcher nich initialisierten Schleifenvariablen redest du ueberhaupt ?
Peer
--- CrossPoint v3.02 R
* Origin: Vanity Fair (2:2448/803.26)
- Marcus
*** Am Freitag 14. Juni 1996 um 23:50 schrieb Peter Marbaise an Siegmund
Schreiber%R:
PM>>> for (;;)
PM>>> printf("Wert : %i\n",i++);
SS>> Schleifenbedingung ist damit immer FALSE.
PM> richtig erkannt !
falsch gelobt.
PM> Man kann ueber das i++ in der printf streiten,
Nein, kann man nicht.
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)
Habe ich mittlerweile getan. Das war natürlich großer Mist von mir!
Siegmund
HR>In C ist auch das völlig legal:
HR> for(i = 4711; *p++; z +=3, i = f(i - 7));
HR>Eine for-Schleife *ohne* Rumpf!
Selbst das hier ist legal:
for (;;);
... das Programm landet zwar in einer Endlosschleife, die *NIX* tut, aber
es ist syntaktisch korrekt.
Bevor Pascal-Freaks jammern: auch in Pascal/Modula kann man sowas, dort
ist es nur umstaendlicher - wie alles in Pascal ;)
WHILE TRUE DO BEGIN END;
°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°
° °
° If we don't love you - °
° °
° LOVE INC. you are ÜÛÛÛÛÛÜ ÜÛÛÛÛÛÜ ÛÛ °
° ÛÛÜÜÜÜ ÛÛ ÛÛ ÛÛ °
° ßßßßÛÛ ÛÛ ÛÛ ÛÛ °
° ßÛÛÛÛÛß ßÛÛÛÛÛß ÛÛÛÛÛÛÛ °
° °
°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°
--- CrossPoint v3.11
* Origin: Love is it! (2:2437/914.6)
Herbert Rosenau wrote in a message to Siegmund Schreiber%R:
HR> In C ist auch das voellig legal:
HR> for(i = 4711; *p++; z +=3, i = f(i - 7));
HR> Eine for-Schleife *ohne* Rumpf!
Oh ja, das ist eine meiner liebsten Programm-Strukturen und ein
wesentlicher Grund dafuer, dass ich mich mit Pascal niemals werde
anfreunden koennen ;-)
Ich finde
for ( i=0; i+1 < maxSize && buf [i]; i++ )
;
einfach viel huebscher und uebersichtlicher als
i := 0;
WHILE (i+1 < maxSize) AND (buf [i] <> CHR(0)) DO
INC (i);
Tschuess,
Steffen
--- FastEcho 1.40+
* Origin: Warum guckst'n Du so ?! (2:2452/112.14)
13 Jun 96 20:58, Marcus Ohlhaut%M4 wrote to Soenke Mueller-Lund:
>> Es findet in C niemals ein Abbruch bei Ueberlauf von Integern statt.
MM> int i=1;
MM> for (;i;i++);
MM> bricht ab, wenn i einmal seinen Wertebereich durchlaufen hat und auf 0
MM> kommt, oder bin ich da voellig C-unwissend? (Falls dem so ist,
MM> verratet es nicht meinem Broetchengeber :-)
Hier testest Du ja auch kontrolliert auf einen Ueberlauf und WILLST dann
abbrechen. Immer vorausgesetzt, Dir ist klar, dass ein int bei einem Ueberlauf
wieder bei 0 anfaengt. ;-) Ich nehme mal an, Soenke meinte damit, dass kein
undefinierter Abbruch bei einem Ueberlauf stattfindet.
14 Jun 96 23:50, Peter Marbaise wrote to Siegmund Schreiber%R:
[...]
PM>>> int i = 0;
PM>>> for (;;)
[...]
SS>> Die Schleifenbedingung ist damit immer FALSE.
PM> richtig erkannt !
Wo ist das richtig? Die Schleifenbedingung ist immer TRUE, sonst waere es ja
keine Endlos-Schleife. Nochmal zur verdeutlichung: die Schleife wird solange
durchlaufen, solange die Schleifenbedingung zu TRUE evaluiert.
18 Jun 96 07:36:32, <Ulrich Simon> to <Herbert Rosenau>:
> HR>In C ist auch das völlig legal:
> HR> for(i = 4711; *p++; z +=3, i = f(i - 7));
> HR>Eine for-Schleife *ohne* Rumpf!
> Selbst das hier ist legal:
> for (;;);
> ... das Programm landet zwar in einer Endlosschleife, die *NIX* tut,
> aber es ist syntaktisch korrekt.
> Bevor Pascal-Freaks jammern: auch in Pascal/Modula kann man sowas, dort
> ist es nur umstaendlicher - wie alles in Pascal ;)
Es ist immer peinlich, wenn sich ein selbsternannter Dozent in seinem eigenen
Topic verheddert. Pascal-Freaks jammern nicht, auch wenn Du es Dir zu wuenschen
scheinst. Auch wissen Pascal-Freaks im Gegensatz zu Dir, wie man eine
Endlosschleife moeglichst kurz notiert.
> WHILE TRUE DO BEGIN END;
WHILE TRUE DO
> °°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°
> ° °
> ° If we don't love you - °
> ° °
> ° LOVE INC. you are ÜÛÛÛÛÛÜ ÜÛÛÛÛÛÜ ÛÛ °
> ° ÛÛÜÜÜÜ ÛÛ ÛÛ ÛÛ °
> ° ßßßßÛÛ ÛÛ ÛÛ ÛÛ °
> ° ßÛÛÛÛÛß ßÛÛÛÛÛß ÛÛÛÛÛÛÛ °
> ° °
> °°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°
Auch Dein Footer scheint in der TEENTALK.GER besser aufgehoben zu sein.
Herzlichst
Horst
--- FMail 1.02
* Origin: -= Berlin, tierra florida =- (2:2410/601.16)
US> WHILE TRUE DO BEGIN END;
OT, aber geht kuerzer: WHILE TRUE DO;
(BEGIN und END brauchst du nur zum Blocken mehrerer Anweisungen!)
MfG, Erhard!
--- FleetStreet 1.12.1 NR
* Origin: Gib GATES keine Chance =)B==o) (2:2487/3001.65)
18 Jun 96 07:49:20, <Steffen Offermann> to <Herbert Rosenau>:
> HR> In C ist auch das voellig legal:
> HR> for(i = 4711; *p++; z +=3, i = f(i - 7));
> HR> Eine for-Schleife *ohne* Rumpf!
> Oh ja, das ist eine meiner liebsten Programm-Strukturen und ein
> wesentlicher Grund dafuer, dass ich mich mit Pascal niemals werde
> anfreunden koennen ;-)
> Ich finde
> for ( i=0; i+1 < maxSize && buf [i]; i++ )
> ;
> einfach viel huebscher und uebersichtlicher als
> i := 0;
> WHILE (i+1 < maxSize) AND (buf [i] <> CHR(0)) DO
> INC (i);
_Uebersichtlicher_ kann nicht Dein Ernst sein. Jeder nicht-Programmierer sieht,
was in dem Pascal-Konstrukt passiert. Dass != 0 in einem logischen C-Ausdruck
redundant ist, erhebt nicht zum Dogma, dass Redundanzfreiheit damit automatisch
fuer das menschliche Auffassungsveroegen _uebersichtlich_ ist.
Wenn Du jetzt einschaenkst "fuer einen C-Programmierer uebersichtlicher"
verliert Deine Aussage jeden Wert, denn dann ist Dein Massstab auf Deine
Vorliebe geeicht und per definitionem subjektiv.
Das C-Konstrukt ist vielleicht kuerzer und kryptischer (huebscher :), wuerde
aber IMHO durch
for ( i=0; i <= maxSize && buf [i] != 0 ; i++ )
kaum Uebersichtlichkeit einbuessen ;-)
cu
TS>Nein, kann man nicht.
Man kann über alles streiten, wenn man genug Zeit hat ;)
cu
Torsten
> Ich finde
> for ( i=0; i+1 < maxSize && buf [i]; i++ )
> ;
> einfach viel huebscher und uebersichtlicher als
> i := 0;
> WHILE (i+1 < maxSize) AND (buf [i] <> CHR(0)) DO
> INC (i);
HK> _Uebersichtlicher_ kann nicht Dein Ernst sein.
Wie bitte ?!
HK> Jeder nicht-Programmierer sieht, was in dem Pascal-Konstrukt
HK> passiert.
Was interessieren mich denn Nicht-Programmierer? Ich urteile na-
tuerlich vom Standpunkt eines Programmierers. Und zwar insbeson-
dere vom Standpunkt eines solchen Programmierers, der beide Spra-
ken schon eingesetzt hat. Fuer mich ist C wesentlich uebersicht-
licher als Pascal, und den Grund dafuer habe ich schon oft genug
genannt: In Pascal ist viel zu viel redundanter Unfug in die Syn-
tax eingebaut worden, der Auge und Gehirn uebermaessig belastet.
Ausserdem sind die Moeglichkeiten, einem Pascal-Quelltext ein
aesthetisches optisches Design zu geben, sehr beschraenkt. Von
der Effizienz der jeweiligen Syntax wollen wir hier mal gar nicht
reden, darueber sind wir uns vermutlich eh einig.
HK> Dass != 0 in einem logischen C-Ausdruck redundant ist, erhebt
HK> nicht zum Dogma, dass Redundanzfreiheit damit automatisch fuer
HK> das menschliche Auffassungsveroegen _uebersichtlich_ ist.
Das ist auch nicht der Knackpunkt in meinem Beispiel gewesen. Ich
habe ueber diese Sache nicht einmal nachgedacht, weil das fuer mich
inzwischen selbstverstaendlich geworden ist (und fuer einen C-
Programmierer in jedem Fall tatsaechlich uebersichtlicher ist).
HK> Wenn Du jetzt einschaenkst "fuer einen C-Programmierer ueber-
HK> sichtlicher" verliert Deine Aussage jeden Wert, denn dann ist
HK> Dein Massstab auf Deine Vorliebe geeicht und per definitionem
HK> subjektiv.
Unsinn, das waere nur dann der Fall, wenn ich ausser C keine Sprache
kennen wuerde. Das ist das Problem bei vielen Pascal-Programmierern,
die C nur "mal gesehen" haben. Die halten diese Sprache natuerlich
unkorrekterweise fuer kryptisch und schwierig. Vergleichen darf aber
nur der, der sich mit beiden Sprachen auseinandergesetzt hat.
Uebrigens habe ich kuerzlich beim Aufraeumen einige Ausdrucke uralter
Quelltexte in die Finger bekommen und war erstaunt, wie viele Pro-
gramme ich in Pascal geschrieben habe. Allerdings nur, weil ich keine
andere Wahl hatte (ich hatte damals keinen C-Compiler fuer den PC) ;-)
HK> Das C-Konstrukt ist vielleicht kuerzer und kryptischer (huebscher
HK> :), wuerde aber IMHO durch
HK> for ( i=0; i <= maxSize && buf [i] != 0 ; i++ )
HK> kaum Uebersichtlichkeit einbuessen ;-)
Kein Zweifel, damit koennte ich auch leben. Manchmal, je nach
Situation, mache ich das sogar selbst so. Aber auch so ist es im
Vergleich zum Pascal-Konstrukt noch um Etliches lesbarer.
... zumindest fuer meine Augen und meinen Verstand ;-)
HK> > WHILE (i+1 < maxSize) AND (buf [i] <> CHR(0)) DO
HK> > INC (i);
HK> _Uebersichtlicher_ kann nicht Dein Ernst sein. Jeder
nicht-Programmierer
HK> sieht, was in dem Pascal-Konstrukt passiert.
Das mag ich aber sehr zu bezweifeln. Wenn jemand noch nie in seinem Leben
nen Source verstanden hat, dann wird er auch hierbei nicht wissen, was das
heisst. Nichteinmal dann, wenn er Englisch verstehen kann.
_cu_
Ingo Riedel (IR)
--- CrossPoint v3.11
* Origin: Co-Sysop der Caliban BBS (2:2448/610.1)
US> for (;;);
US> ... das Programm landet zwar in einer Endlosschleife, die *NIX* tut, aber
US> es ist syntaktisch korrekt.
Und? Sinn?
US> Bevor Pascal-Freaks jammern: auch in Pascal/Modula kann man sowas, dort
US> ist es nur umstaendlicher - wie alles in Pascal ;)
US> WHILE TRUE DO BEGIN END;
Quack - umständlich machen das nur die Cähler, so geht's:
WHILE true DO;
(entspricht einem "while (1);" )
oder auch
REPEAT UNTIL false;
(entspricht "do {} while (1);" )
Und? Sinn?
(so wie Dein Footer? =];)
MfG, S. Schicktanz - acht zwei fuenf vier sieben Achmuehle / Eurasburg
--- Msgedsq/2 3.10
* Origin: Friend of Murphy's - (08171) 16402 [voice/fax]. (2:2480/642.25)
TS>> Nein, kann man nicht.
TL> Man kann ueber alles streiten, wenn man genug Zeit hat ;)
Aba 1 is chlor: diese einseitigen... aeh... Einzeiler von Thomas
[ ] kesseln einfach nich...
Wa?
Michael
--- CrossPoint v3.02 R
* Origin: Du kannst ueberholen... die Wolken brechen auf... (2:2453/30.77)
Es war aber schlichtweg falsch, und ich habe nicht die Absicht, mich durch
irgendwelche Ausreden herauswinden zu wollen. Was ist so schlimm daran, sich
für Fehler zu entschuldigen?
Siegmund
MR>Aba 1 is chlor: diese einseitigen... aeh... Einzeiler von Thomas
MR> [ ] kesseln einfach nich...
MR> Wa?
ROTFL! Warst Du schon drinne?
cu
Torsten
PM> Tja mit dem FALSE (was es in C eigentlich nicht gibt) komme ich auch
PM> prompt durcheinander. Ciao Peter
----reiss----beiss---knabber---knurpsel---------------------ruelps!
/* The Truth or not The Truth - that is the question...
*
* Michael Ringel, 1996
*
*/
#include <stdio.h>
void main(void)
{
int thisFlag = 0;
if(thisFlag) {
printf("\n#define TRUE %d", thisFlag);
printf("\n#define FALSE %d", !thisFlag);
} else {
printf("\n#define TRUE %d", !thisFlag);
printf("\n#define FALSE %d", thisFlag);
SS> Quack - umstaendlich machen das nur die Caehler, so geht's:
SS>
SS> WHILE true DO;
Umstaendlich machen's die Pasaler, so geht's:
HELL: goto HELL;
SS> Und? Sinn?
Keiner. Wozu auch?
Michael
Peter Marbaise schrieb an Thomas Seeling am 29.06.96:
PM> Tja mit dem FALSE (was es in C eigentlich nicht gibt) komme ich auch
PM> prompt durcheinander. Ciao Peter
Ich habe einen grossen Zettel an der Wand haengen:
FALSE = 0
:-)
Bye,
Tobias!
--- FleetStreet 1.15+
* Origin: Yau! (2:2437/350.7)
SS>> Quack - umstaendlich machen das nur die Caehler, so geht's:
SS>>
SS>> WHILE true DO;
> Umstaendlich machen's die Pasaler, so geht's:
>
> HELL: goto HELL;
for(;;);
SS>> Und? Sinn?
> Keiner. Wozu auch?
Doch, das macht einen Sinn. Mit so einem Progrämmchen kann man die
Performance eines Betriebssystems testen (und ich vermute, daß dieser
Thread durch diese Motivation entstanden ist).
Natürlich kann das ein kleiner bedeutungsloser Hacker wie Du, der noch
niemals aus seiner DOSe herausgekrochen ist, das nicht ahnen. Wie soll
denn auch jemand aus einer zweidimensionalen Welt wissen, wozu ein Würfel
gut ist?
Ciao
Sönke
"My homepage is my castle"
MR> Umstaendlich machen's die Pasaler, so geht's:
MR> HELL: goto HELL;
Einfacher:
while(1);
MR>HELL: goto HELL;
Jehova!
Cu
Uli
--- CrossPoint v3.11
* Origin: Sorry fuer den Footer der letzten mails (2:2437/914.6)
MR>> Umstaendlich machen's die Pasaler, so geht's:
MR>> HELL: goto HELL;
ES> Einfacher:
ES> while(1);
viel zu umstaendlich und um drei Ecken gedacht... :)
Es geht _nichts_ ueber ein schoenes, klares, geradliniges goto!
(Insbesondere nicht in Diskussionen mit Pasalern, die es ja fertigbringen,
selbst "while(1);" noch als strukturierte Programmierung zu verhoekern :)
Ueberprueft habe ich's nicht, aber vermutlich ist auch der Assemblercode
fuer goto kuerzer. Muesste mit hoechstens 3 Bytes machbar sein.
Michael
PS: Sinn? Ich hoer immer "Sinn"? Keiner! Wozu auch....
> ...bla...
> Doch, das macht einen Sinn. Mit so einem Progrämmchen kann man die
> Performance eines Betriebssystems testen (und ich vermute, daß dieser
> Thread durch diese Motivation entstanden ist).
> Natürlich kann das ein kleiner bedeutungsloser Hacker wie Du, der noch
> niemals aus seiner DOSe herausgekrochen ist, das nicht ahnen. Wie soll
> denn auch jemand aus einer zweidimensionalen Welt wissen, wozu ein
Würfel
> gut ist?
>
[grinz] GUT GEBRÜLLT - LÖWE !
aber haber wir nicht alle einmal klein angefangen ? und ist nicht dos eine
der grundlagen für viele programmierer ? ich meine wer in seinem
programmiererleben noch kein dos programmiert hat, der hat etwas wichtiges
verpaßt ! so viele schweinereien, sog. tricks und absturzszenarien wie
unter dos kann man in keinem anderen betriebssystem erleben. und erst
dieses fieber bei der fehlersuche - "dann wars doch ein tsr-programm, das
mir in den code geschrieben hat" usw...
also - nicht die kleinen kinder schimpfen während sie noch krabbeln - wenn
sie zu früh mit dem laufen beginnen wollen und zu oft auf die nase fallen
werden sie aufgeben es zu versuchen !
Frank Benkert
frank_...@frb.franken.de
Frank_...@mgn.maus.de
Frank Benkert @ MGN
MR> Es geht _nichts_ ueber ein schoenes, klares, geradliniges goto!
Es ist inzwischen mathematisch nachweisbar, dass _jede_ Aufgabenstellung,
die
ueberhaupt loesbar ist, auch ohne GOTO loesbar ist. GOTO ist ein Befehl,
der in
keinem, aber absolut keinem Programm irgendeine Berechtigung haette. Das
geht
viel schoener auf anderen Wegen. Zu dem Thema existiert AFAIK sogar schon
eine
Doktorarbeit (muss mal meinen Komilitonen fragen, der hat das Ding mal
gelesen).
MR> (Insbesondere nicht in Diskussionen mit Pasalern, die es ja
fertigbringen,
MR> selbst "while(1);" noch als strukturierte Programmierung zu
verhoekern :)
Endlosschleifen haben natuerlich nichts mit Struktur zu tun. Sie sind aber
sowieso verboten (ausser in Betriebssystemen).
MR> Ueberprueft habe ich's nicht, aber vermutlich ist auch der
Assemblercode
MR> fuer goto kuerzer. Muesste mit hoechstens 3 Bytes machbar sein.
Ein Compiler mit Optimierung macht das genau gleich lang.
label:
goto label;
und
while (1);
produzieren selbstverstaendlich bei jedem Compiler, der sein
Geld wert ist, denselben Assemblercode.
Auf meinem Linux-System (steinalte Installation mit aktuellem
Kernel):
root@white:/tmp# cc -v
Reading specs from /usr/lib/gcc-lib/i486-linux/2.6.3/specs
gcc version 2.6.3
Das folgende Programm:
root@white:/tmp# cat x.c
main() {
while(1);
}
wird dann mit
root@white:/tmp# cc -O6 -S x.c
zu dem folgenden Assemblercode:
root@white:/tmp# cat x.s
.file "x.c"
gcc2_compiled.:
___gnu_compiled_c:
.text
.align 4
.globl _main
_main:
pushl %ebp
movl %esp,%ebp
call ___main
.align 2,0x90
L7:
jmp L7
.align 4,0x90
root@white:/tmp#
Uebersetzt man auch y.c:
root@white:/tmp# cat y.c
main() {
label:
goto label;
}
und vergleicht, bekommt man ganz wie erwartet
root@white:/tmp# diff -0 -u x.s y.s
--- x.s Fri Jul 12 10:28:48 1996
+++ y.s Fri Jul 12 10:29:59 1996
@@ -1 +1 @@
- .file "x.c"
+ .file "y.c"
@@ -11,3 +11,2 @@
- .align 2,0x90
-L7:
- jmp L7
+L4:
+ jmp L4
oder mit anderen Worten bis auf Isomorphie gleichen Code.
Zum Thema "ueberprueft habe ich das nicht": Das angestrebte
Ziel bei der Optimierung von Compilaten ist es, semantisch
gleichen Code in physikalisch gleichen Code zu uebersetzen.
while(1) und label: goto label sind semantisch gleich (beide
produzieren eine Endlosschleife ohne Zustandsaenderung). Zudem
handelt es sich strukturell noch um extrem einfachen Code.
Optimizier, die beide Konstrukte identisch uebersetzen, schreibt
man in jedem Codegenerierung I Praktikum.
Mit anderen Worten: Sogar Borland sollte inzwischen einen
Compiler hinbekommen haben, der beides in einen simplen "jmp"
uebersetzt.
Kristian
--
Kristian Koehntopp, Wassilystrasse 30, 24113 Kiel, +49 431 688897
Inkomploehntopp: http://nuki.netuse.de/~kk/inkomploehntopp/
Generation @
--- FIDOGATE 3.9.3
* Origin: Fido-Gateway @ white.schulung.netuse.de (2:240/2123.59)
>Endlosschleifen haben natuerlich nichts mit Struktur zu tun. Sie sind aber
>sowieso verboten (ausser in Betriebssystemen).
Wo lebst Du ?
Endlosschleifen sind ne coole Sache (insbesondere bei irgendwelchen
Handlern, die immer nur ueberpruefen, ob nen Ereignis vorliegt (zum
Bleistift Maus bewegt oder net?))...
Replys Cc as email please!
bye...
Alexander |||
( o o )
-----------------------------OOO--` - '---OOO-
| Alexander Lucke, |
| Email: <a...@next2.psychologie.hu-berlin.de> |
| WWW: <http://141.20.111.4/al/> |
----------------------------------------------
- Marcus
Alexander Lucke wrote in a message to Erhard Schwenk:
ES> Endlosschleifen haben natuerlich nichts mit Struktur zu tun. Sie
ES> sind aber sowieso verboten (ausser in Betriebssystemen).
Voellig richtig.
AL> Wo lebst Du ?
Die Frage (wenngleich sie nicht mir galt) gebe ich mal gleich
postwendend zurueck ;-)
AL> Endlosschleifen sind ne coole Sache (insbesondere bei irgend-
AL> welchen Handlern, die immer nur ueberpruefen, ob nen Ereignis
AL> vorliegt (zum Bleistift Maus bewegt oder net?))...
Das ist, so leid es mir tut, das sagen zu muessen, hochgradiger
Unsinn. Wenn ich Dich fuer Deine Programme bezahlen muesste und
mitbekaeme, dass Du so programmierst, wuerde ich Dich hinauswer-
fen ;-)
Vermutlich hast Du keine Erfahrung mit Multitasking-Betriebssy-
stemen, darum erlaeutere ich kurz, woran die obige Methode
krankt:
Eine Endlosschleife wird ununterbrochen durchlaufen und beansprucht
damit dauerhaft die CPU. Auf Single-Processing-Systemen wie MS-DOS
ist dieses als Polling bezeichnete Verfahren nicht ganz so schlimm
wie in Multitasking-Umgebungen, aber schlechter Stil ist es ganz
ohne Frage. In einer Multitasking-Umgebung bewirkt die Endlosschlei-
fe, dass der entsprechende Prozess allen anderen Prozessen fast die
gesamte CPU-Zeit abzieht und das System somit mehr oder weniger
stillsteht. Richtig ist, das Programm in der Zeit, in der es nichts
Wichtiges zu tun hat, "schlafenzulegen" und nur dann zu aktivieren,
wenn Bedarf besteht. Auf Systemen wie OS/2 oder Windows 95 bzw. NT
werden hierzu Semaphoren verwendet. Der Prozess wartet auf das
Setzen des vom System verwalteten Semaphors, d.h., er wird vom
System stillgelegt und erst wieder aktiviert, wenn der Semaphor
gesetzt wurde. In Single-Tasking-Systemen besteht die Moeglichkeit,
Interrupt-Routinen zu verwenden, die nur aufgerufen werden, wenn
ein bestimmter Interrupt ausgeloest wurde.
SO> Es gibt eben _doch_ Situationen, in denen eine Loesung
SO> ohne "goto" zwar _machbar_ ist, wobei sich dann aber der Auf-
SO> wand fuer eine Loesung mit Schleifenkonstrukten und Abbruch-
SO> bedingungen nicht rechnet, zumal die Lesbarkeit des Programm-
SO> textes dann beeintraechtigt wird.
ES> Bei einem sauberen Design ist das eben nicht der Fall.
Du siehst das zu engstirnig. Es ist richtig, dass in den aller-
meisten Faellen durch geschicktes Desing die Verwendung von
goto-Anweisungen _sinnvoll_ vermieden werden kann. Es ist aber
definitiv falsch, diesen Umstand zu pauschalisieren. Ich stehe,
wie Du, auf dem Standpunkt, dass Funktionen durchschnittlich
nicht laenger als ein paar Dutzend Zeilen werden sollten, und
dass tiefverschachtelte Schleifen vermieden und stattdessen
mehrere Funktionsaufrufe verwendet werden sollten. Aber: Es ist
nicht damit getan, sich immer nur auf eine gute Programmstruktur
zu berufen und dabei das Ziel aus den Augen zu verlieren. In
zeit- oder speicherkritischen Situationen kann es durchaus eine
Menge ausmachen, wenn ein Funktionsaufruf mehr oder weniger in
einer Schleife steckt. Und in solchen Situationen kann auch bei
mir eine Funktion mehr als drei ineinander verschachtelte Schlei-
fen aufweisen und im Notfall durch ein goto beendet werden. Zu-
gegeben, dass sind Ausnahmefaelle, aber sie kommen vor.
ES> Das ist ja der Gag. Du musst dir nur mal von Vorneherein
ES> ueberlegen, wie das ganze strukturiert werden soll. Wenn du
ES> natuerlich VHIDT ("Vom Hirn in die Tasten") programmierst,
ES> kann das nix werden. Das sollte aber bei Programmen mit mehr
ES> als 10 LOC (Lines Of Code) nicht mehr der Fall sein.
Du irrst Dich. Gerade weil man _nicht_ unueberlegt drauflos
programmieren sollte, sind goto-Anweisungen nicht immer und
ueberall Teufelszeug. Wie gesagt: Schoene Struktur ist gut und
schoen, aber sie darf nicht zum Selbstzweck entarten.
Bitte komme jetzt nicht mit dem heutzutage oft und gerne ange-
fuehrten Argument "aber wir haben doch schnelle Rechner und viel
Speicher". Genau das ist ja die Ursache fuer die bestaendig sin-
kende Qualitaet der heutigen Programmierer bzw. Programme, und
diese Einstellung _fuehrt_ ja erst zu der Notwendigkeit, immer
schnellere CPUs und groessere Platten zu bauen. Eingelaeutet
wurde dieses Zeitalter der Verschwendung von Microsoft und Kon-
sorten.
ES> Da gibst in fast allen Faellen sogar ne kuerzere Methode ohne
ES> Goto.
Na, das nun sicher nicht.
ES> Ich hab das frueher auch nicht geglaubt, aber wenn du ne
ES> ordentliche Analyse- und Design-Methode einsetzt, kannst du
ES> von Vorneherein gar keine "Goto-verdaechtige" Situation in
ES> dein Programm bringen, und jedes Goto wird das Programm dann
ES> nur aufblaehen und unuebersichtlich machen. Uebrigens: In
ES> fast allen Faellen kommt man sogar ohne das beruechtigte
ES> "break" aus, das genauso strukturzerstoerend sein kann.
Fuer break gilt in meinen Augen exakt die gleiche Argumentation
wie fuer goto. Ich vermeide beide Anweisungen, wo immer es geht,
aber im Zweifelsfall hat in meinen Programmen Effizienz immer
Vorrang vor Designfragen.
SO> Ich finde, dass man hier nicht pauschal fuer oder gegen
SO> "goto" stimmen kann.
ES> Doch, man kann.
Ein klarer Standpunkt, aber ohne Argument ;-)
SO> Und Eines sollte auch bitte nicht vergessen werden: In der
SO> Sprache des Prozessors werden "goto"-Anweisungen am laufenden
SO> Band eingesetzt, ohne dass sich jemand darueber beschwert.
ES> In Assembler programmiert ja auch kein Mensch eine richtige
ES> Anwendung.
Aber hallo! Dass _Du_ das nicht tust (ich in der Regel uebrigens
auch nicht), ist doch nicht automatisch ein Beweis dafuer, dass
es _niemand_ tut... oder dass diejenigen, die Assembler einsetzen,
schlechtere Programmierer sind.
ES> Die Goto's im Objektcode kommen auch nur daher, dass die
ES> JC's nicht weit genug reichen. Ausserdem ist das ein voellig
ES> anderes Problem.
Noe, ist es naemlich ganz und gar nicht. Genau das ist der Punkt:
In Assembler wird auf Redundanz verzichtet, die in Hochsprachen
zwangslaeufig entsteht. Das Ergebnis ist, sofern der Programmierer
nicht voellig sinnlos herumhackt, ein im Hinblick auf Effizienz
optimierter Code. Effizienz und Struktur sind eben nicht immer
vollstaendig miteinander unter einen Hut zu bringen.
Tschuess,
Steffen
--- FastEcho 1.40+
* Origin: I miss Windows - but my aim is getting better! (2:2452/112.14)
AL>> Endlosschleifen sind ne coole Sache (insbesondere bei irgendwelchen
AL>> Handlern, die immer nur ueberpruefen, ob nen Ereignis vorliegt (zum
AL>> Bleistift Maus bewegt oder net?))...
> Das ist absolut schwachsinnig, sowas in ner Endlosschleife zu handeln.
da hast Du recht.
> kooperative Multitasker wie Windows bringst du damit sogar
> unter bestimmten Umstaenden voellig zum Stillstand.
Nun, ein Windows-Programm durchläuft genaugenommen immer eine
Endlosschleife:
MSG msg;
while( GetMessage( &msg, NULL, 0, 0 ) )
{
TranslateMessage( &msg );
DispatchMessage( &msg );
}
Ok, eine Abbruchbedingung ist drin, aber sie könnte auch wegfallen und
würde den Ablauf von Windows nicht weiter stören.
> Ein Ereignis muss immer eine Nachricht ausloesen, normalerweise in Form
> eines Interrupts
Klingt DOS-lastig.
[ ... ]
: Ende = 0; /* alternativ: Ende = FALSE */
: while (!Ende)
: {
: ...
: }
:
: Denn das ist genau das, was du programmierst, nur kann bei dir niemand sagen,
: wodurch die Schleife denn nun abgebrochen wird, weil du irgendwo mittendrin ein
: Goto hinter das Schleifenende setzt bzw. das Programm innerhalb der Schleife
: mit exit() oder so beendest. Und das ist ganz schlechter Stil. Was machst du
: z.B., wenn du in 5 oder 10 Jahren unmittelbar vor dem Beenden des Programms
: noch schnell den Bildschirmmodus zurueckschalten willst? Bei o.g. Variante
: setzt du ein clearscreen() oder so was direkt hinter die while-Schleife und das
: ganze ist beendet. Wenn du da mit exit()'s arbeitest (womoeglich noch mit
: mehreren) - viel Spass beim Suchen. Natuerlich koenntest du deine eigene exit()
: einbinden, aber das ist noch unuebersichtlicher. Auch die goto- bzw.
: break-Variante weist aehnliche Macken auf. Also Frage zurueck: wo lebst du?
Was ist eigentlich an obiger while Schleife, bei der dann irgendwo ein
Ende = 1; steht schoener oder besser als eine Schleife ohne
Abbruchbedingung, und an der Stelle wo Ende = 1 steht, halt ein break;
Wann und wo abgebrochen wird, ist bei beiden Varianten gleich gut erkennbar,
nur das ich bei der "Ende" Version u.U. noch ein paar zusaetzliche if-Abfragen
brauche.
Oder anders gefragt, was ist an break und continue eigentlich so schlecht?
Ich verwend vor allem break recht gern.
Herbert
--
Herbert Kremser | "On the Internet,
kre...@flinux.tu-graz.ac.at | nobody knows
kre...@sbox.tu-graz.ac.at | you're a dog."
*** Am Montag 22. Juli 1996 um 19:30 schrieb Steffen Offermann an Alexander
Lucke:
SO> ist dieses als Polling bezeichnete Verfahren nicht ganz so schlimm
SO> wie in Multitasking-Umgebungen
SO> wenn Bedarf besteht. Auf Systemen wie OS/2 oder Windows 95 bzw. NT
SO> werden hierzu Semaphoren verwendet. Der Prozess wartet auf das
SO> Setzen des vom System verwalteten Semaphors, d.h., er wird vom
SO> System stillgelegt und erst wieder aktiviert, wenn der Semaphor
SO> gesetzt wurde.
Die Implementation des Semaphore-Konzepts sieht dann vor, dass eine Liste von
PIDs gespeichert wird, die aufzuwecken sind, wenn mit der Semaphore etwas
passiert. Damit kann der Prozess definitiv auf Eis gelegt werden und bekommt
erst wieder Rechenzeit, wenn sein Aufweckereignis eintritt.
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)
[...]
HE>> da hat "goto" schon seine Meriten
ES> Eine so tief verschachtelte Schleife ist ein Strukturfehler.
Gut, reduzieren wir die Verschachtelungstiefe auf Ebene 3, und ich muss
mit einem Satz aus der innersten Schleife raus.
It's up to you ...
ES> Wenn einer ne Schleife, aus der du so rausspringst,
ES> spaeter aendern muss und dein goto nicht sieht, hat er beim Debuggen
ES> ein riesengrosses Problem.
Interessiert mich nicht: an meine Sourcen lass ich (ausser mir) naemlich
nur Wasser und CD :-)
meinjanur: R.
--- Blue Wave/RA v2.12 [NR]
* Origin: Mainframe Support System 49-6171-76295 (2:244/1153)
- Marcus
Gut gebrüllt Löwe.
Es gibt immer noch viele Anwendungen, die z.T. nur durch Polling realisiert
werden können.
Es gibt auch noch unzählige Mikroprozessorlösungen, die auf diesem Wege
erfolgreich arbeiten und es wird sie auch in Zukunft noch eine ganze Weile
geben.
Und der Markt für Spiele ist gewaltig und dort sind die Anforderungen an die
Programme ganz anders.
Auch Programmierer von Mulitasking-Umgebungen sollten ab und zu mal über ihren
Tellerrand schauen...
Siegmund
SO> Du siehst das zu engstirnig.
Eher im Gegenteil.
SO> Es ist richtig, dass in den aller-
SO> meisten Faellen durch geschicktes Desing die Verwendung von
SO> goto-Anweisungen _sinnvoll_ vermieden werden kann. Es ist aber
SO> definitiv falsch, diesen Umstand zu pauschalisieren.
Diese pauschalisierung ist wie gesagt AFAIK sogar mathematisch beweisbar.
SO> Ich stehe,
SO> wie Du, auf dem Standpunkt, dass Funktionen durchschnittlich
SO> nicht laenger als ein paar Dutzend Zeilen werden sollten, und
SO> dass tiefverschachtelte Schleifen vermieden und stattdessen
SO> mehrere Funktionsaufrufe verwendet werden sollten. Aber: Es ist
SO> nicht damit getan, sich immer nur auf eine gute Programmstruktur
SO> zu berufen und dabei das Ziel aus den Augen zu verlieren. In
SO> zeit- oder speicherkritischen Situationen kann es durchaus eine
SO> Menge ausmachen, wenn ein Funktionsaufruf mehr oder weniger in
SO> einer Schleife steckt. Und in solchen Situationen kann auch bei
SO> mir eine Funktion mehr als drei ineinander verschachtelte Schlei- fen
SO> aufweisen und im Notfall durch ein goto beendet werden. Zu- gegeben, dass
SO> sind Ausnahmefaelle, aber sie kommen vor.
Die kommen aber heutzutage kaum noch vor, und dann nimmt man den weiter unten
zitierten Assembler. In den meisten realen Anwendungen hast du diese
Situationen aber nicht, und ueberdies ist es um ein vielfaches billiger, 10-20
000 DM in leistungsfaehigere Hardware zu stecken als um ein paar Millisekunden
rauszukitzeln das Programm so zu vermurksen, dass die Wartung unmoeglich wird
und man das ganze deshalb bei der naechsten groesseren Aenderung komplett neu
entwickeln darf. Professionelle Anwendungen interessieren sich heute eigentlich
kaum noch fuer die zur Verfuegung stehende Rechenleistung. Und das ist auch gut
so. 99% aller GOTO's, die ich bisher sah, kamen eindeutig von der Faulheit der
jeweiligen Programmierer oder aud mangelndem Strukturverstaendnis bzw.
Designfehlern.
SO> Du irrst Dich. Gerade weil man _nicht_ unueberlegt drauflos
SO> programmieren sollte, sind goto-Anweisungen nicht immer und
SO> ueberall Teufelszeug. Wie gesagt: Schoene Struktur ist gut und
SO> schoen, aber sie darf nicht zum Selbstzweck entarten.
Wenn man ueberlegt (das heisst mit Analyse- und Design-Methoden) arbeitet, dann
kann gar kein goto entstehen. Das sehen die ueblichen A- und D- Methoden
naemlich schon vom Modell her gar nicht vor. Wenn du ein goto hast, hast du
entweder mies designt oder du programmierst an deinem design vorbei, beides
sind todsuenden schlechthin.
SO> Bitte komme jetzt nicht mit dem heutzutage oft und gerne ange-
SO> fuehrten Argument "aber wir haben doch schnelle Rechner und viel
SO> Speicher". Genau das ist ja die Ursache fuer die bestaendig sin-
SO> kende Qualitaet der heutigen Programmierer bzw. Programme, und
SO> diese Einstellung _fuehrt_ ja erst zu der Notwendigkeit, immer
SO> schnellere CPUs und groessere Platten zu bauen. Eingelaeutet
SO> wurde dieses Zeitalter der Verschwendung von Microsoft und Kon-
SO> sorten.
Rechenleistung ist wesentlich billiger als Entwicklerleistung. Wenn du ne
Ahnung von BWL hast, kannst du das jederzeit nachpruefen. Eine Stunde
Entwicklerleistung kostet dich mindestens 250 DM. Wenn so ein Mann zwei Tage
beschaeftigt ist, altlasten aus dem Code zu entfernen, ist der teurere Rechner
schon ewig bezahlt. Und oft ziehen solche scheinbar schnelle loesungen einen
ganzen Rattenschwanz an Spaetfolgen nach sich.
SO> Ein klarer Standpunkt, aber ohne Argument ;-)
Ohne Argument? Was habe ich dann die letzten drei Mails dargestellt?
ES>> In Assembler programmiert ja auch kein Mensch eine richtige
ES>> Anwendung.
SO> Aber hallo! Dass _Du_ das nicht tust (ich in der Regel uebrigens
SO> auch nicht), ist doch nicht automatisch ein Beweis dafuer, dass
SO> es _niemand_ tut... oder dass diejenigen, die Assembler einsetzen,
SO> schlechtere Programmierer sind.
Hat niemand behauptet. Aber in Assembler wird heutzutage kaum noch ernsthaft
programmiert, und wenn, dann nur einzelne hardware-spezifische Aufrufe oder
extrem Zeitkritische Teile. RISC-Prozessoren kannst du z.B. in Asm kaum noch
von hand programmieren, da sie auf den optimierenden und korrigierenden
COmpiler der Hochsprache abgestimmt sind. Wenn du mal versucht hast, nen Proz
zu programmieren, der z.B. immer den ersten Befehl nach einem bedingten Sprung
noch mit ausfuehrt, dann weisst du, was ich meine. Ausserdem sind kommerzielle
Anwendungen zu wertvoll und teuer, um an eine einzelne Plattform auf Dauer
gebunden zu bleiben. Das Risiko geht kein vernuenftiger DV-Manager ein.
SO> Noe, ist es naemlich ganz und gar nicht. Genau das ist der Punkt: In
SO> Assembler wird auf Redundanz verzichtet, die in Hochsprachen zwangslaeufig
SO> entsteht. Das Ergebnis ist, sofern der Programmierer nicht voellig sinnlos
SO> herumhackt, ein im Hinblick auf Effizienz optimierter Code. Effizienz und
SO> Struktur sind eben nicht immer vollstaendig miteinander unter einen Hut zu
SO> bringen.
Sie sind es aber meist, und ausserdem ineressiert Effizienz kaum noch. Das war
mal zu Zeiten, als Speicher und Rechenleistung noch teuer waren, aber heute
geht es meist nur noch darum, ob du hundertstel oder ne tausendstel Sekunde auf
deine Eingabemaske wartest, und derartige Antwortzeiten sind dem Anwender nun
wirklich egal. Da gibts eher andere Bremsen, z.B. im WAN-Bereich, die wirklich
zu schaffen machen. Und schliesslich: Assembler ist in erster Linie
Wegwerf-Code, der kaum wartbar und nicht portierbar ist. Allein deshalb wird er
gemieden wie die Pest. Programme werden heutzutage normalerweise nach folgenden
Kriterien erstellt:
1) Funktion
2) Bedienbarkeit, Konsistenz
3) Robustheit
4) Moeglichkeit der Einbindung in bestehende Strukturen
5) Wiederverwendbarkeit, Portierbarkeit
6) Wartbarkeit und Struktur, Erweiterbarkeit
7) Effizienz
Du siehst, die Effizienz steht ganz am Schluss. Rechenleistung ist heute kaum
noch ein Thema, denn bei den meisten Anwendungen hat man sie eh im Ueberfluss.
Hoechstens die I/O-Leistung spielt etwa bei Datenbankservern noch ne Rolle.
Wenn die Rechenleistung nicht ausreicht, ist es einfacher, das Unix-Cluster um
ne Maschine zu erweitern (zumal in Gross-DV-Anlagen sowieso fast immer jede
Anwendung ihre "eigene" Maschine hat), als Generationen von Entwicklern mit
sinnlosen Optimierungen zu binden, die spaetestens bei der naechsten
Rechnergeneration wieder rausfallen.
HK> : Ende = 0; /* alternativ: Ende = FALSE */
HK> : while (!Ende)
HK> : {
HK> : ...
HK> : }
HK> :
HK> Was ist eigentlich an obiger while Schleife, bei der dann irgendwo ein
Ende
HK> = 1; steht schoener oder besser als eine Schleife ohne Abbruchbedingung,
HK> und an der Stelle wo Ende = 1 steht, halt ein break;
HK> Wann und wo abgebrochen wird, ist bei beiden Varianten gleich gut
HK> erkennbar, nur das ich bei der "Ende" Version u.U. noch ein paar
HK> zusaetzliche if-Abfragen brauche.
HK> Oder anders gefragt, was ist an break und continue eigentlich so schlecht?
HK> Ich verwend vor allem break recht gern.
An break und continue ist schlecht, dass Anweisungen uebersprungen werden, ohne
dass dies auf den ersten Blick strukturell auffaellt.
Wenn ich eine Schleife sehe, suche ich am Anfang (oder evtl. am Ende) der
Schleife nach den Abbruchbedingungen. Und ich erwarte dann auch, dass alle
Abbruchbedingungen dort aufgezaehlt sind. Das hat den Vorteil, dass ich in
einem speziellen Fall nur eine Stelle im Code ansehen muss und nicht 25
verschiedene. Damit ist eine potentielle Fehlerquelle bei spaeteren
Programmaenderungen von Vorneherein ausgeschaltet.
Wenn du mal umfangreichen Code gesehen hast, weisst du warum. Wenn in ner 50
Seiten langen Funktion, die im Prinzip nur aus ner while-Schleife und ner
case-Konstruktion besteht, irgendwo in der mitte ein unzulaessiges break steht,
das du beim Warten uebersiehst, dann debuggst du daran unter Umstaenden
Tagelang und fragst dich, warum dein Code gar nicht erst ausgefuehrt wird. Die
Definition der Schleifenbedingungen gehoert eben logisch zum while() und nicht
zu irgend nem if in der Mitte. Deshalb ist es besser, Abbruchbedingungen (und
zwar _alle_ Abbruchbedingungen) an den Anfang (oder bei repeat-Schleifen ans
Ende, je nachdem, wo die Bedingung geprueft wird) zu stellen. Damit erkennst du
solche Dinge auf den ersten Blick. Diese breaks zeigen eigentlich nur, dass du
begonnen hast, die Schleife zu codieren, bevor du dir ueber die
Abbruchbedingungen im klaren warst, sprich, du hast beim Design geschlampt.
HE> [...]
HE>>> da hat "goto" schon seine Meriten
ES>> Eine so tief verschachtelte Schleife ist ein Strukturfehler.
HE> Gut, reduzieren wir die Verschachtelungstiefe auf Ebene 3, und ich muss
mit
HE> einem Satz aus der innersten Schleife raus. It's up to you ...
while (!ende && (Bedingung1))
{
while (!ende && (Bedingung2))
{
while (!ende && (Bedingung3))
{
if (Abbruch)
ende = 1;
else
{
}
}
if (!ende)
{
...
}
}
if (!ende)
{
...
}
}
Sieht komplizierter aus, aber spaetestens, wenn eine der "if
(!ende)"-Konstruktionen nen else-Zweig bekommen soll, ist der Vorteil zu
erkennen. Und du sollst ja schliesslich robuste Programme schreiben, oder?
Moeglicherweise gibts auch noch ne bessere Methode, aber diese funktioniert und
ist strukturell und logisch sauber.
Ach ja: Die if(!ende)...-Konstruktionen kann man sich sparen, wenn die
Verschachtelung jeweils am Ende der uebergeordneten Schleife stattfindet. Das
geht aber wirklich nicht immer.
ES>> Wenn einer ne Schleife, aus der du so rausspringst,
ES>> spaeter aendern muss und dein goto nicht sieht, hat er beim Debuggen ein
ES>> riesengrosses Problem.
HE> Interessiert mich nicht: an meine Sourcen lass ich (ausser mir) naemlich
HE> nur Wasser und CD :-)
Damit sind deine Sourcen aber fuer jeden potentiellen Kaeufer indiskutabel.
Zumindest fuer mich. Uebrigens: Auch du selbst wirst dieses Problem nach
einiger Zeit haben.
*** Am Dienstag 23. Juli 1996 um 12:23 schrieb Soenke Mueller-Lund%KI an Erhard
Schwenk:
SMLK> Nun, ein Windows-Programm durchlaeuft genaugenommen immer eine
SMLK> Endlosschleife:
SMLK> MSG msg;
SMLK> while( GetMessage( &msg, NULL, 0, 0 ) )
SMLK> {
SMLK> TranslateMessage( &msg );
SMLK> DispatchMessage( &msg );
SMLK> }
Darin ist aber auch exakt die "Kooperation" zu erkennen: es werden
Betriebsystemaufrufe getaetigt, genaugenommen gibt also das Programm permanent
Rechenzeit ab, und in Get..., Trans... oder Dis... kann ein anderer Prozess an
die Reihe kommen.
SM> Nun, ein Windows-Programm durchlaeuft genaugenommen immer eine
SM> Endlosschleife:
SM> MSG msg;
SM> while( GetMessage( &msg, NULL, 0, 0 ) )
SM> {
SM> TranslateMessage( &msg );
SM> DispatchMessage( &msg );
SM> }
SM> Ok, eine Abbruchbedingung ist drin, aber sie koennte auch wegfallen und
SM> wuerde den Ablauf von Windows nicht weiter stoeren.
Sie ist aber trotzdem vorhanden, und sie steht da, wo sie hingehoert, naemlich
am Schleifenanfang. Das ist keine Endlosschleife, sondern eine Schleife, die
ausgefuehrt wird, solange das Programm keine Ende-Message bekommen hat. Das ist
schon ein gewisser Unterschied und auch auf jeden Fall sauberer Stil.
>> Ein Ereignis muss immer eine Nachricht ausloesen, normalerweise in Form
>> eines Interrupts
SM> Klingt DOS-lastig.
Nee, ist ja nur ein Beispiel. Ein "Interrupt" kann prinzipiell in fast allen
Systemen generiert werden, und wenn du OO arbeitest, ist eine Nachricht
eigentlich auch nichts anderes.
SO> Auf Systemen wie OS/2 oder Windows 95 bzw. NT werden hierzu
SO> Semaphoren verwendet. Der Prozess wartet auf das Setzen des
SO> vom System verwalteten Semaphors, d.h., er wird vom System
SO> stillgelegt und erst wieder aktiviert, wenn der Semaphor
SO> gesetzt wurde.
TS> Die Implementation des Semaphore-Konzepts sieht dann vor,
TS> dass eine Liste von PIDs gespeichert wird, die aufzuwecken
TS> sind,
Um es ganz genau zu machen: Die Prozessliste existiert sowieso
immer, es wwerden lediglich Flags gesetzt, die darueber Auskunft
geben, ob ein Prozess laeuft (RUNNING), auf das Aufwecken wartet
(BLOCKED) oder vom System wegen eines Interrupts oder aus anderen
Gruenden (Multitasking) unterbrochen wurde (READY).
TS> wenn mit der Semaphore etwas passiert.
Nur am Rande: "die Semaphore" gibt es nicht. Das Wort Semaphor
ist im Deutschen entweder maskulin oder neutrum, wobei ich per-
soenlich die maskuline Form "der Semaphor" vorziehe.
TS> Damit kann der Prozess definitiv auf Eis gelegt werden und
TS> bekommt erst wieder Rechenzeit, wenn sein Aufweckereignis
TS> eintritt.
So ist es. Aber das hatte ich ja eigentlich auch schon gesagt ;-)
Tschuess,
Steffen
--- FastEcho 1.40+
Marcus Ohlhaut%M4 wrote in a message to Steffen Offermann:
>Der Prozess wartet auf das Setzen des vom System verwalteten
>Semaphors, d.h., er wird vom System stillgelegt und erst wieder
>aktiviert, wenn der Semaphor gesetzt wurde.
MM> Jein. "Der Prozess wartet" heisst ja wohl, dass der Prozess
MM> waehrend dieser Zeit etwas tut (zB. den Zustand der Semaphore
MM> abfragt) - in einer Schleife gar?
Nein, die Formulierung ist schon richtig - fuer den Prozess
stellt sich die Sache tatsaechlich so dar, dass er auf ein Er-
eignis wartet. Dass in der Zwischenzeit keinerlei Rechenzeit
an diesen Prozess abgegeben wird (die er ja auch nicht benoe-
tigt), liegt ja nicht im Einfluss des Prozesses sondern des
Betriebssystems.
MM> Besser formuliert ist "Der Prozess bekommt vom Scheduler
MM> keine CPU-Zeit, bis der Scheduler festgestellt hat, dass
MM> die Semaphore gesetzt wurde".
Na sicher, genau das habe ich ja geschrieben (Du hast es sogar
zitiert): Der Prozess wird vom System stillgelegt und erst
wieder aktiviert, wenn der Semaphor gesetzt wurde.
Aber - wie kommt Ihr nur alle auf die irrige Idee, dass das Wort
"Semaphor" feminin sei? ;-)
MM> Der Scheduler uebrigens laeuft in einer Endlosschleife (bei
MM> vernuenftigen OS!)
Das tut er wohl bei jedem Betriebssystem - wie sollte es auch
anders (sinnvoll) moeglich sein? Schliesslich ist der Scheduler
der einzige Prozess, der _immer_ aktiv sein muss.
ES> Professionelle Anwendungen interessieren
ES> sich heute eigentlich kaum noch fuer die zur Verfuegung
ES> stehende Rechenleistung.
Das kann ich so nicht stehen lassen. Im Grossrechnerbereich
kriegt der Kunde sehr wohl die Auswirkung eines schlechten
Programmes zu spueren, und zwar in harter Mark. Es ist ein
Unterschied, ob du fuer 2000 DM im Monat Produktionskosten
erzeugst oder fuer 50.000. Im Client Markt sieht die Sache
natuerlich ganz anders aus, da dort so gut wie keine
Produktionskosten anfallen, sondern nur einmal Investitionen in
Sachen Hardware. Bei den heutigen Hardwarepreisen und Lohnkosten
ist die Sache klar, wo man optimiert. Das bedeuted natuerlich
nicht, das man schlampigen Code akzeptiert. Und Schoenheit im
Code bekommt man auch nicht bezahlt. Man kann "schoenen" (=
strkturierten) Code auf n Varianten produzieren, wobei die mit
geringerer Laufzeit natuerlich vorzuziehen sind. Man sollte schon
noch im Auge behalten, was man mit seinem Code so an Laufzeit
fabriziert, und ueberlegen, ob es nicht was besseres gibt.
Aber mit C hat das alles nur noch wenig zu tun.
au revoir
Rainer
--- CrossPoint v3.11 R
* Origin: Noctambule lunatique qui clignote dans le soir (2:2435/610.21)
Woher stammt diese Aufstellung?
Siegmund
MO> Der Scheduler uebrigens laeuft in einer Endlosschleife (bei
MO> vernuenftigen OS!)
Richtig. Deshalb sind OS auch die einzige Ausnahme bezueglich der "Erlaubtheit"
von Endlosschleifen (auch wenn das strenggenommen immer noch keine
Endlosschleifen sind, denn sie werden mit dem Herunterfahren des Systems
beendet). In jedem anderen Programm, insbesondere in Anwendungen, sind
Endlosschleifen jedoch designmaessig _verboten_.
am 25.07.96 06:05 erzähltest Du Steffen
>>werden hierzu Semaphoren verwendet. Der Prozess wartet auf das Setzen des
>> vom System verwalteten Semaphors, d.h., er wird vom System stillgelegt
>> und erst wieder aktiviert, wenn der Semaphor gesetzt wurde. In
>> Single-Tasking-Systemen besteht die Moeglichkeit,
MO> Jein. "Der Prozess wartet" heisst ja wohl, dass der Prozess waehrend
MO> dieser Zeit etwas tut (zB. den Zustand der Semaphore abfragt)
Ja, er WARTET. D.h., sein Status in der prozeßtabelle ist "wait". Warten in
einer MT-Umgebung ist eben etwas ganz anderes, als unter DOS.
MO> - in einer Schleife gar? Besser formuliert ist "Der Prozess bekommt
MO> vom Scheduler keine CPU-Zeit, bis der Scheduler festgestellt hat, dass
MO> die Semaphore gesetzt wurde". Der Scheduler uebrigens laeuft in einer
MO> Endlosschleife (bei vernuenftigen OS!)
Nope. Der Scheduler ist nur aktiv, wenn
- sein Timer abgelaufen ist
- ein Prozeß etwas von ihm will
Ansonsten wartet er selbst. Er läuft nur, wenn er auch etwas zu tun hat. Alles
andere ist sinnloses Verbraten von CPU-Zeit.
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)
Am 28.07.96 00:00 schrieb Rainer Huebenthal an Erhard Schwenk :
RH> Im Grossrechnerbereich kriegt der Kunde sehr wohl die Auswirkung
eines
RH> schlechten Programmes zu spueren,
[...]
RH> Aber mit C hat das alles nur noch wenig zu tun.
Das mag wohl sein, aber Threads wie z.B. dieser momentan machen dieses
Echo
eigentlich noch fuer die Leute lesenswert, die nicht "im PM mit XXCC++++
und
massig `ASM' etwas `coden' wollen".
Leider scheint es kein geeignetes Echo zu geben, in dem hauptsaechlich
uber
derlei "Meta-Fragen" zur Software-Erstellung diskutiert wird.
Schoenen Tag noch,
Arndt
--- Sqed/32 1.10/r00135
* Origin: Home of the brave (2:2454/116.42)
*** Am Samstag 27. Juli 1996 um 16:43 schrieb Steffen Offermann an Thomas
Seeling:
SO> Nur am Rande: "die Semaphore" gibt es nicht. Das Wort Semaphor
SO> ist im Deutschen entweder maskulin oder neutrum, wobei ich per-
SO> soenlich die maskuline Form "der Semaphor" vorziehe.
Ich sage "die Semaphore" und mein Sprachgefuehl ist zufrieden damit.
> while (!ende && (Bedingung1))
> {
> while (!ende && (Bedingung2))
> {
> ...
bei aller Liebe. Übersichtlich und wartbar finde ich das ganz und gar
nicht. Da ziehe ich doch lieber break, return oder goto vor.
> Sieht komplizierter aus, aber spaetestens, wenn eine der "if
> (!ende)"-Konstruktionen nen else-Zweig bekommen soll, ist der Vorteil zu
> erkennen.
?
> Moeglicherweise gibts auch noch ne bessere Methode, aber diese funktioniert
> und ist strukturell und logisch sauber.
IYO, wirklich nur IYO!
>Richtig. Deshalb sind OS auch die einzige Ausnahme bezueglich der
"Erlaubtheit"
>von Endlosschleifen (auch wenn das strenggenommen immer noch keine
>Endlosschleifen sind, denn sie werden mit dem Herunterfahren des Systems
>beendet). In jedem anderen Programm, insbesondere in Anwendungen, sind
>Endlosschleifen jedoch designmaessig _verboten_.
In so ziemlich jedem eventgesteuerten Programm hast Du einen
Scheduler fuer Events - bei einem Betriebssystem sind diese
Events Unterbrechungen jeder Art, bei einem Anwendungsprogramm
z.B. Messages vom GUI-System (TimerEvent, MouseDownEvent,
MenuSelectionEvent und so weiter).
Der Scheduler fuer solche Dinge hat in der Regel die Form einer
Endlosschleife.
Kristian
--
Kristian Koehntopp, Wassilystrasse 30, 24113 Kiel, +49 431 688897
"ICH HABE EINE WELTANSCHAUUNG. SIE IST GUT UND RICHTIG. SIE BERUHT
AUF DEN MODERNSTEN ERGEBNISSEN DER QUANTENPHYSIK UND AUF EINEM
LAECHELN IM GESICHT." ruft Peter Berlich, Physiker, in de.talk.bizarre
(uebermaessiges Quoten schadet der Gesundheit, dennoch:)
['tiefe Schleifen' und 'goto'...]
HE>> Gut, reduzieren wir die Verschachtelungstiefe auf Ebene 3, und ich
HE>> muss mit einem Satz aus der innersten Schleife raus. It's up to you
...
ES> while (!ende && (Bedingung1))
ES> {
ES> while (!ende && (Bedingung2))
ES> {
ES> while (!ende && (Bedingung3))
ES> {
ES> if (Abbruch)
ES> ende = 1;
ES> else
ES> {
ES> }
ES> }
ES> if (!ende)
ES> {
ES> }
ES> }
ES> if (!ende)
ES> {
ES> }
ES> }
Tscha, bei schaut das dann ungefaehr so aus:
while (blafasel) {
while (rhabarber){ /* Oops; man merkt, dass ich vom Theater komme? :-)
*/
while (wen_interessiert_das_eigentlich_ueberhaupt_noch) {
if (ganz_ganz_schlimme_angelegenheit)
goto winke_mit_dem_faehnchen_und_rufe_dabei_laut_um_hilfe;
}
}
}
Auch du wirst zugeben muessen, das obiges Konstrukt ein klein wenig
kuerzer
ist als dein Loesungsvorschlag...
(vielleicht sogar ein klein wenig schneller; aber die paar 'if-Abfragen',
das spielt bei heutigen Prozessoren ja keine Rolle mehr)
but to heck with it: ich wuerde vorschlagen, dass wir das jetzt lassen;
alldieweil, so langsam naehern wir uns einer eher metaphysischen Ebene ...
Falls du jedoch weitermachen willst, bitte sehr, keine Hemmungen :-)))
meinjanur: R.
PS: irgendwie kommt es mir vor, als habest du C (und vielleicht auch 'Pro-
grammierung allgemein') mehr von der theoretischen Seite aus erlernt. Das
soll jetzt kein Vorwurf sein, nur:
- Was ist das groesste Gefaelle der Welt?
- Das Gefaelle zwischen Theorie und Praxis.
Herbert Rosenau wrote in a message to Marcus Ohlhaut%M4:
MO> Der Scheduler uebrigens laeuft in einer Endlosschleife (bei
MO> vernuenftigen OS!)
HR> Nope. Der Scheduler ist nur aktiv, wenn
HR> - sein Timer abgelaufen ist
HR> - ein Prozess etwas von ihm will
Das stimmt natuerlich. Aber, auch wenn Marcus das zugegenermassen
in diesem Fall anders meinte (und damit unrecht hat ;-)) : Der
Scheduler laeuft natuerlich tatsaechlich in einer Endlosschleife
und ist immer praesent.
29 Jul 96 17:03, Thomas Seeling wrote to Steffen Offermann:
SO>> Nur am Rande: "die Semaphore" gibt es nicht. Das Wort
SO>> Semaphor ist im Deutschen entweder maskulin oder neutrum,
SO>> wobei ich persoenlich die maskuline Form "der Semaphor"
SO>> vorziehe.
TS> Ich sage "die Semaphore" und mein Sprachgefuehl ist zu-
TS> frieden damit.
Aber der Duden nicht ;-))
Wenn Du mich fragst (tust Du nicht, weiss ich ja ;-)), klingt
"die Semaphore" genauso ulkig wie "die Fensterin" oder "der
Telefon".
Tschuess,
Steffen
---
* Origin: P.I.L Grevenbroich, FRG, 49-2181-64021 (2:2433/1860)
AH> machen dieses Echo eigentlich noch fuer die Leute
AH> lesenswert, die nicht "im PM mit XXCC++++ und massig `ASM'
AH> etwas `coden' wollen". Leider scheint es kein geeignetes
AH> Echo zu geben, in dem hauptsaechlich uber derlei
AH> "Meta-Fragen" zur Software-Erstellung diskutiert wird.
PGMRS.GER. Genau dafuer da.
Aber solange hier geduldet/toleriert, werde ich mein GOTO
natuerlich verteidigen :-)
30 Jul 96 00:09, Arndt Hoffmann wrote to Rainer Huebenthal:
AH> Das mag wohl sein, aber Threads wie z.B. dieser momentan machen dieses
AH> Echo eigentlich noch fuer die Leute lesenswert, die nicht "im PM mit
AH> XXCC++++ und massig `ASM' etwas `coden' wollen". Leider scheint es
AH> kein geeignetes Echo zu geben, in dem hauptsaechlich uber derlei
AH> "Meta-Fragen" zur Software-Erstellung diskutiert wird.
INFORMATIK.GER ?
PGMRS.GER ?
Im uebrigen bin ich Deiner Meinung. Solche Themen sind mit Sicherheit
interessanter, als die nte Frage wie ich den Bildschirmspeicher direkt
anspreche etc.
ByE/2,
MarKus.
--- (c) Frobozz Magic Tearline Company
* Origin: xxx (2:2454/505.69)
SO> Du siehst das zu engstirnig.
ES> Eher im Gegenteil.
Naja :-*
SO> Es ist richtig, dass in den allermeisten Faellen durch
SO> geschicktes Desing die Verwendung von goto-Anweisungen
SO> _sinnvoll_ vermieden werden kann. Es ist aber
SO> definitiv falsch, diesen Umstand zu pauschalisieren.
ES> Diese pauschalisierung ist wie gesagt AFAIK sogar mathe-
ES> matisch beweisbar.
Nein, das stimmt natuerlich nicht. Ob etwas _sinnvoll_ ist,
kann mit mathematischen Mitteln ganz sicher nicht bewiesen
werden. Du bringst da etwas durcheinander: Natuerlich ist
es immer moeglich, goto-Anweisungen _irgendwie_ (ja, sogar
mittels allgemeingueltiger Verfahren) zu eliminieren, aber
dass die Struktur dadurch immer _besser_ wird ist ganz ein-
fach Unsinn. Gegenbeispiele habe ich bereits genannt.
SO> Es ist nicht damit getan, sich immer nur auf eine gute
SO> Programmstruktur zu berufen und dabei das Ziel aus den
SO> Augen zu verlieren. In zeit- oder speicherkritischen
SO> Situationen kann es durchaus eine Menge ausmachen, wenn
SO> ein Funktionsaufruf mehr oder weniger in einer Schleife
SO> steckt. Und in solchen Situationen kann auch bei mir eine
SO> Funktion mehr als drei ineinander verschachtelte Schlei-
SO> fen aufweisen und im Notfall durch ein goto beendet
SO> werden. Zugegeben, dass sind Ausnahmefaelle, aber sie
SO> kommen vor.
ES> Die kommen aber heutzutage kaum noch vor, und dann nimmt
ES> man den weiter unten zitierten Assembler.
Ich nicht. Die Zeiten, in denen ich laut "Assembler" gerufen
habe, wenn ich etwas schneller und/oder kleiner hinbekommen
wollte, sind schon lange vorbei. Heutzutage ist das auch nicht
mehr sinnvoll, da moderne Hochsprachencompiler oft ebensoguten
Code erzeugen wie handoptimierte Assemblerquelltexte. Man muss
als Programmierer nur geschickt genug programmieren, um dem
Compiler solche Optimierungen zu ermoeglichen. Durch die Ein-
fuehrung zahlreicher Zusatzvariablen fuer bedingte Abbrueche
oder durch die Aufteilung vieler kleiner Aktionen auf mehrere
Funktionen wird eine solche Optimierung zunichte gemacht. Darum
bleibe ich dabei: Prinzipiell ist es angebracht, so zu program-
mieren, wie Du es forderst, und in der Regel fordere ich das
auch selbst. Aber es gibt unbestreitbar Situationen, in denen
zugunsten der Effizienz die Struktur in den Hintergrund treten
muss. Ich weigere mich strikt, diese Thematik, wie Du, nur
schwarz und weiss zu sehen. Es gibt grundsaetzlich keine All-
zweckmethode, die _immer_ optimal ist.
ES> In den meisten realen Anwendungen hast du diese Situationen
ES> aber nicht, und ueberdies ist es um ein vielfaches billiger,
ES> 10-20 000 DM in leistungsfaehigere Hardware zu stecken als
ES> um ein paar Millisekunden rauszukitzeln das Programm so
ES> zu vermurksen, dass die Wartung unmoeglich wird und man das
ES> ganze deshalb bei der naechsten groesseren Aenderung komplett
ES> neu entwickeln darf.
Die Ausnahmefaelle, von denen ich spreche, erstrecken sich nicht
ueber mehrer Kilobytes an Quelltexten, insofern greift Dein Ar-
gument nicht. Im Uebrigen schraenkst Du schon wieder Deinen
Blickwinkel zu sehr ein: Ich rede hier nicht nur von Firmen, die
mehrere Tausende Mark aus dem Hut zaubern koennen, um in Hard-
und Software zu installieren sondern auch vom Otto-Normal-Pro-
grammierer und -Anwender. Die wollen auch irgendwo bleiben, und
ich persoenlich sehe es langsam nicht mehr ein, andauernd teures
Geld fuer immer bessere Hardware auszugeben, weil ein paar grosse
Softwarehaeuser schlechte Software zum Weltstandard erklaeren.
ES> Professionelle Anwendungen interessieren sich heute eigent-
ES> lich kaum noch fuer die zur Verfuegung stehende Rechen-
ES> leistung.
Eben. Und das ist es, was ich allem voran bemaengele. Ich habe
schon einige sogenannte "professionelle" Programme gesehen, die
alles andere als professionell programmiert waren.
ES> Und das ist auch gut so.
Naja.
ES> 99% aller GOTO's, die ich bisher sah, kamen eindeutig von
ES> der Faulheit der jeweiligen Programmierer oder aud mangeln-
ES> dem Strukturverstaendnis bzw. Designfehlern.
Ein Programm, auf das diese Aussage sicherlich voll und ganz
zutrifft, ist Binkley Term. Aber die Tatsache, dass es schlechte
Beispiele fuer den Einsatz von "goto" gibt, fuehrt doch nicht
automatisch zu der Interpretation, dass e" generell Unsinn ist.
SO> Du irrst Dich. Gerade weil man _nicht_ unueberlegt drauflos
SO> programmieren sollte, sind goto-Anweisungen nicht immer und
SO> ueberall Teufelszeug. Wie gesagt: Schoene Struktur ist gut
SO> und schoen, aber sie darf nicht zum Selbstzweck entarten.
ES> Wenn man ueberlegt (das heisst mit Analyse- und Design-Me-
ES> thoden) arbeitet, dann kann gar kein goto entstehen. Das
ES> sehen die ueblichen A- und D- Methoden naemlich schon vom
ES> Modell her gar nicht vor. Wenn du ein goto hast, hast du
ES> entweder mies designt oder du programmierst an deinem design
ES> vorbei, beides sind todsuenden schlechthin.
Sei mir nicht boese, aber alles, was Du bisher angefuehrt hast,
klingt verdammt theoretisch und praxisfern. Ich bin selbst In-
formatiker und kenne die Gefahr, die vom Informatik-Studium
ausgeht: Man lernt viele schoene Methoden und Modelle kennen,
die sich im Vorlesungsskript und bei Vortraegen renommierter
Professoren ausnehmend gut anhoeren. Dabei verliert man aber
nur zu gerne den Blick fuer die Realitaet und erkennt nicht
mehr, dass im wirklichen Leben eben doch nicht alles so exakt
zusammenpasst wie im theoretischen Modell. Was passieren kann,
wenn man allzu theorieglaeubig ist, zeigen Auswuechse wie die
sogenannten Programmiersprachen Pascal oder gar Modula-2.
SO> Bitte komme jetzt nicht mit dem heutzutage oft und gerne
SO> angefuehrten Argument "aber wir haben doch schnelle Rechner
SO> und viel Speicher".
Das hast Du ja nun leider doch getan :-(
SO> Genau das ist ja die Ursache fuer die bestaendig sinkende
SO> Qualitaet der heutigen Programmierer bzw. Programme, und
SO> diese Einstellung _fuehrt_ ja erst zu der Notwendigkeit,
SO> immer schnellere CPUs und groessere Platten zu bauen.
ES> Rechenleistung ist wesentlich billiger als Entwicklerlei-
ES> stung.
Das mag fuer grosse Firmen gelten, die ein entsprechendes Budget
zur Verfuegung haben. Aber die Welt besteht nicht nur aus solchen
Firmen.
ES> Wenn du ne Ahnung von BWL hast, kannst du das jederzeit
ES> nachpruefen.
Schon wieder blanke Theorie und Verallgemeinerung ;-)
ES> Eine Stunde Entwicklerleistung kostet dich mindestens 250 DM.
ES> Wenn so ein Mann zwei Tage beschaeftigt ist, altlasten aus
ES> dem Code zu entfernen, ist der teurere Rechner schon ewig
ES> bezahlt. Und oft ziehen solche scheinbar schnelle loesungen
ES> einen ganzen Rattenschwanz an Spaetfolgen nach sich.
Vielleicht solltest Du einmal nicht nur den Entwickler sehen
sondern auch den Anwender.
SO> Ein klarer Standpunkt, aber ohne Argument ;-)
ES> Ohne Argument? Was habe ich dann die letzten drei Mails
ES> dargestellt?
Immer dasselbe ;-)
Wie gesagt, ich halte Deine Auffassung fuer zu therorielastig
und vermisse den Bezug zur Realitaet. Du versuchst laufend,
ein idealisiertes Modellbild zu vertreten und gehst auf pra-
xisorientierte Gegenargumente nicht ein.
SO> In Assembler wird auf Redundanz verzichtet, die in Hoch-
SO> sprachen zwangslaeufig entsteht. Das Ergebnis ist, sofern
SO> der Programmierer nicht voellig sinnlos herumhackt, ein
SO> im Hinblick auf Effizienz optimierter Code. Effizienz und
SO> Struktur sind eben nicht immer vollstaendig miteinander
SO> unter einen Hut zu bringen.
ES> Sie sind es aber meist, und ausserdem ineressiert Effizienz
ES> kaum noch. Das war mal zu Zeiten, als Speicher und Rechen-
ES> leistung noch teuer waren,
Also, tut mir leid, aber fuer mich sind auch 99,- DM fuer ein
8 MB-Modul (das ja heute auch nicht mehr annaehernd ausreicht)
noch viel Geld, und ein Pentium ist auch nicht gerade billig.
Und die Entwicklung stoppt ja nicht, sondern man stopft ohne
Ende Luecken. In Kuerze werde ich 64 MB RAM auf meinem Arbeits-
rechner haben, und ich wette, dass das in gar nicht allzu fer-
ner Zukunft auch schon wieder unterste Kiste ist. Mein Pentium
133 ist ja jetzt schon fuer solche Monstren wie Windows NT ge-
rade mal gut genug.
ES> aber heute geht es meist nur noch darum, ob du hundertstel
ES> oder ne tausendstel Sekunde auf deine Eingabemaske wartest,
ES> und derartige Antwortzeiten sind dem Anwender nun wirklich
ES> egal.
Und darum geht es in den Anwednungbereichen, an die ich denke,
eben nicht. Ich spreche zum Beispiel von langwierigen Rechen-
operationen oder umfangreichen Datenbankzugriffen, von opti-
mierten Zeichenoperationen, usw...
ES> Da gibts eher andere Bremsen, z.B. im WAN-Bereich, die
ES> wirklich zu schaffen machen. Und schliesslich: Assembler
ES> ist in erster Linie Wegwerf-Code, der kaum wartbar und
ES> nicht portierbar ist. Allein deshalb wird er gemieden
ES> wie die Pest.
Das stimmt natuerlich, aendert aber nichts an der Tatsache,
dass auch heute noch Anwendungsgebiete fuer Assembler exi-
stieren. Ich denke da nur an die (mir so verhasste) Spiele-
programmierung unter MS-DOS.
Kristian =?ISO-8859-1?Q?K=F6hntopp? wrote in a message to All:
K=> In so ziemlich jedem eventgesteuerten Programm hast Du einen
K=> Scheduler fuer Events - bei einem Betriebssystem sind diese
K=> Events Unterbrechungen jeder Art, bei einem Anwendungsprogramm
K=> z.B. Messages vom GUI-System (TimerEvent, MouseDownEvent,
K=> MenuSelectionEvent und so weiter).
K=> Der Scheduler fuer solche Dinge hat in der Regel die Form
K=> einer Endlosschleife.
Nein, hat er nicht. Jedenfalls nicht, wenn er sauber programmiert
ist, denn ein solcher Scheduler muss ja auch irgendwie zu beenden
sein (und eben nicht durch Ctrl-C). Bei mir haben solche Scheduler-
Schleifen die folgende Struktur:
do
{
error = DosWaitMuxWaitSem ( hMuxWait,
SEM_INDEFINITE_WAIT,
&which );
if ( !error )
{
ULONG count;
DosResetEventSem ( eventTab [which].hSem, &count );
if ( eventTab [which].flags & STOP_SCHED )
done = TRUE;
else
runCommand ( eventTab [which].command,
eventTab [which].args );
}
}
while ( !done );
So koennen naemlich alle Programmstrukturen sauber aufgeraeumt,
Semaphoren geschlossen und Deinitialisierungen vorgenommen wer-
den.
Kurze Erlaeuterung: Ich verwende einen speziell ausgezeichneten
oeffentlichen Semaphor zur Beendigung des Programms. Dieser
Semaphor ist im obigen Kurzbeispiel in "eventTab" mit gesetztem
Flag STOP_SCHED versehen.
Und fuer Nicht-OS/2-Programmierer: DosWaitMuxWaitSem() wartet
auf das Setzen eines oder mehrerer Semaphoren gleichzeitig.
Die Variable "which" erhaelt eine bei der Einrichtung der
einzelnen Ereignis-Semaphoren zugewiesene ID (ich verwende
dafuer im obigen Beispiel den Index in die Ereignis-Tabelle).
HE> Auch du wirst zugeben muessen, das obiges Konstrukt ein klein wenig
kuerzer
HE> ist als dein Loesungsvorschlag... (vielleicht sogar ein klein wenig
HE> schneller; aber die paar 'if-Abfragen', das spielt bei heutigen
HE> Prozessoren ja keine Rolle mehr)
Die paar if-Abfragen spielen im Allgemeinen tatsaechlich kaum eine Rolle.
Kuerzer ist der Code sicher auch. Aber deshalb noch lange nicht sauberer oder
strukturierter. Das geht, wenn du ne 5-Zeilen-Funktion hast. Wenn du deine
Schleifen aber mal ein bisschen mit Leben fuellst, wirst du schnell sehen, dass
deine Methode recht gefaehrlich werden kann. Uebrigens: das Goto ist auch nicht
ganz so sauber wie es aussieht, denn es erzeugt noch ne Menge
Stack-Aufraeumarbeiten.
HE> but to heck with it: ich wuerde
HE> vorschlagen, dass wir das jetzt lassen; alldieweil, so langsam naehern wir
HE> uns einer eher metaphysischen Ebene ...
Richtig.
HE> PS: irgendwie kommt es mir vor, als habest du C (und vielleicht auch 'Pro-
HE> grammierung allgemein') mehr von der theoretischen Seite aus erlernt. Das
HE> soll jetzt kein Vorwurf sein, nur: - Was ist das groesste Gefaelle der
HE> Welt? - Das Gefaelle zwischen Theorie und Praxis.
Ich habe C und die Programmierung sowohl in der Praxis (ich war z.B. vor 3
Jahren an einem CAD-Projekt beteiligt, und ich programmiere derzeit
kaufmaennische Software fuer eine Bank im Rahmen meines Studiums) als auch in
der Theorie ein klein Wenig kennengelernt. Vor allem aber habe ich mich nicht
nur fuer das einhacken des Codes in die Maschine (das sind bei einem
Entwicklungsprojekt etwa 10% der eigentlichen Arbeit), sondern fuer den
kompletten Vorgang der PRogrammerstellung interessiert. Und der ist nunmal
anerkanntermassen so, dass man zuerst analysiert (aufschreiben, was das
Programm koennen soll, und zwar in allen Details! -> Spezifikation), dann
designt (festlegen, wie das Programm arbeiten soll, ebenfalls detailliert,
daraus entstehen z.B. DFD's, Struktogramme, ER-Modelle und aehnliche Dinge) und
erst dann zur Implementation schreitet. Und wenn man das tut, hat man in den
meisten Faellen auch Erfolg mit dem Projekt. Und man ist, so seltsam es manchen
klingen mag, auch meist schneller, als wenn man sich erstmal hinsetzt und
programmiert und dabei eh nur verzettelt.
ES>> Programme werden heutzutage normalerweise nach folgenden Kriterien
ES>> erstellt: 1) Funktion 2) Bedienbarkeit, Konsistenz 3) Robustheit 4)
ES>> Moeglichkeit der Einbindung in bestehende Strukturen 5)
ES>> Wiederverwendbarkeit, Portierbarkeit 6) Wartbarkeit und Struktur,
ES>> Erweiterbarkeit 7) Effizienz
SS> Woher stammt diese Aufstellung?
Zum Beispiel aus einem Pflichtenheft eines CAD-Projektes, das ich vor 2 oder 3
Jahren mal gelesen habe. Aber auch aus persoenlicher, inzwischen etwa 8 jahre
waehrender Programmiererfahrung mit C, Basic, Assembler, COBOL, SMART, Pascal
(brrr ;), C++, dBase (nur am Rande) und diversen Makro-Sprachen auf diversen
Rechnern (z.B. mach ich grad noch ne Anpassung eines COBOL-Programmes auf ner
MTOS), aber auch aus 5 Semestern Wirtschaftsinformatik an der BA Stuttgart.
Oder aus dem Style-Guide des Sparkassen-Informationszentrums in Bonn (das war
ne Benutzeroberflaechen-Richtlinie fuer alle Sparkassen in Deutschland!). Das
steht aber mehr oder weniger Sinngemaess auch in jedem Standardwerk zur
Informatik, insbesondere bei kommerziell angehauchter Informatik (Wirtschafts-,
technische Informatik und deren Spielarten).
Unbetrachtet dessen muesste einem das aber auch der gesunde Menschenverstand
sagen:
1) Funktion
ein Programm das nicht das macht, was es soll, ist wertlos. Unbeachtet aller
anderen Vorzuege.
2) Bedienbarkeit, Konsistenz
Eine Anwendung, die niemand bedienen kann, ist ebenso wertlos. Gerade das
Bedienungskonzept ist entscheidend, wenn es um die Produktivitaet der Anwender
geht. Schau dir nur mal an, wie lange erfahrene Anwender unterschiedlicher
Textverarbeitungen brauchen, um einen Serienbrief zu erstellen. Da spielt die
Oberflaeche ganz schoen mit.
3) Robustheit
Wenn du mal ein Programm im professionellen Einsatz hattest, weisst du, dass so
ein Programm so robust wie moeglich sein soll. Ein Programm, das nach einer
fehlerhaften Eingabe z.B. sang- und klanglos abstuerzt, ist kaum zu verwenden.
Auch die Debugging-Phase wird kuerzer und einfacher, wenn man mit seinen
eigenen Fehlern rechnet.
4) Moeglichkeit der Einbindung in bestehende Strukturen
Niemand wird seine gesamte Unternehmens- oder Rechnerstruktur aufgeben, um ein
einzelnes Programm einzusetzen. Nur wenn das Programm moeglichst flexibel in
bestehende Strukturen (die nunmal gegeben sind) eingebunden werden kann, ist es
wirklich verwertbar. Das gilt natuerlich nicht nur fuer Computerprogramme
5) Wiederverwendbarkeit, Portierbarkeit
Oft gepredigt, selten realisiert. Trotzdem: Neuentwicklung ist fast immer
teurer, als vorhandenes weiterzuverwenden. Das ist ja z.B. auch ein Grund fuer
den Erfolg von OO-Techniken. Und nur weil der Rechner ausgetauscht wird, darf
nicht auch das muehsam erstellte, zum Teil in jahrelangen Prozessen optimierte
und verbesserte Softwarepaket rausfliegen. Sonst wird das naemlich richtig
teuer. Hardware auszutauschen ist dagegen meist ein Klacks.
6) Wartbarkeit und Struktur, Erweiterbarkeit
Computerprogramme, insbesondere Individualsoftware, sind nie fertig. Sie
muessen staendig an veraenderte Bedingungen angepasst werden, neue Funktionen
werden realisiert, Fehler entfernt usw. usw. Mit einem nicht wartbaren,
unstrukturierten Programm oder einem Programm, das sich nur schwer erweitern
laesst, erzeugst du daher immense Aufwendungen. Diese sind auf die Dauer
betrachtet fast immer viel hoeher als der eigentliche Entwicklungsaufwand fuer
das System oder die Kosten fuer den Betrieb und die Anschaffung der Hardware.
Zudem haben Provisorische Loesungen die seltsame Angewohnheit, leise und ueber
Nacht zu Kernstuecken von Standards zu werden. Deshalb sind Q&D-Hacks wirklich
nur fuer kurze Tests geeignet.
7) Effizienz
Nicht zu verwechseln mit Effektivitaet (die wuerde unter 1) fallen). Erst wenn
ich ein Programm habe, das alle oben genannten Anforderungen erfuellt, kann ich
mich - unter den genannten Voraussetzungen - ans Optimieren machen. Und nur
Optimierungen, die weiter oben nicht wieder Aufwand verursachen wuerden, sparen
tatsaechlich Geld bzw. Zeit. Deshalb nimmt man in der Praxis eben lieber einen
P150 fuer das Programm, als ein Team von 3 Entwicklern Optimierungen einbauen
zu lassen, die dann das Upgraden auf die naechste Version erschweren oder
wieder rausgeschmissen werden muessen. Der groessere Rechner ist z.B. bei
kaufmaennischen Systemen meist ziemlich irrelevant. Erlaubt sind natuerlich
algorithmische Optimierungen (z.B. der Einsatz des Bresenham-Algorithmusses
anstatt einen Kreis mit Fliesskomma-Trigonometrie zu berechnen oder so). Aber
Optimierungen der Marke "Bit-Knipserei! sind nicht nur unnoetig, sondern meist
auch verboten.
So, nun weisst du, wie man auf die Aufstellung kommt ;). Ich hoffe, das klingt
auch fuer dich logisch.
K> Der Scheduler fuer solche Dinge hat in der Regel die Form einer
K> Endlosschleife.
Also, strukturell betrachtet hat er in einem Betriebssystem die Form einer
Endlosschleife. In jedem anderen Programm muesste er die Form einer Schleife
mit der Abbruchbedingung "Programmende" haben. Das ist dann aber keine
Endlosschleife mehr, denn die ist dadurch charakterisiert, dass sie eben keine
Abbruchbedingung hat. Strenggenommen ist sogar die BS-Schleife keine
Endlosschleife, denn sie wird durch das Ausschalten des Rechners beendet. Aber
die Konstruktion while (!MachinePoweredOff) ... waere wohl etwas sinnlos, zumal
jedem wohl klar ist, dass auf ner ausgeschalteten Maschine kein Programm
laeuft. Aber die Beendigungs-Bedingung eines Programms gehoert in meinen Augen
durchaus zum Programmcode.
ES> Unbetrachtet dessen muesste einem das aber auch der gesunde
ES> Menschenverstand sagen:
ES>
ES> 1) Funktion
ES>
ES> ein Programm das nicht das macht, was es soll, ist wertlos.
ES> Unbeachtet aller anderen Vorzuege.
Unvollstaendig :-) Ein Programm muss nicht nur das machen, was es
soll, es darf noch nicht einmal mehr machen.
ES> 7) Effizienz
ES>
ES> Nicht zu verwechseln mit Effektivitaet (die wuerde unter 1)
ES> fallen). Erst wenn ich ein Programm habe, das alle oben
ES> genannten Anforderungen erfuellt, kann ich mich - unter den
ES> genannten Voraussetzungen - ans Optimieren machen.
Falscher Ansatz. Es muss _vorher_ geklaert werden, mit wievielen
Daten das Programm zurande kommen muss und wie komplex die
Beschaffung der Daten ist. Dann sind naemlich rechtzeitig
entsprechende Massnahmen zu ergreifen bzw gleich die richtigen
Alghorythmen auszuwaehlen. Dein Vorschlag sieht jetzt so aus, als
wuerdest erst mal schoen sauber sturkturiert implementieren, und
dann erstaunt feststellen, dass das Programm in Produktion
Stunden laeuft, weil es auf einmal nicht 50 Testsaetze
verarbeiten muss, sondern Millionen. Solche Ueberlegungen
gehoeren schon in das Desgin, denn da kann isch schon festlegen,
ob ich bestimmte Daten seriell brauche oder ob ich die evtl
paralell beschaffen kann, wieviel das sind, auf welche Art eine
Sortierung sinnvoll ist, ob nicht die eine oder andere
Umsortierung notwendig ist etc etc. Das hat dann gravierenden
Einfluss auf die Programme. Wenn du erst designst, und dann
merkst, dass dein Programm ineffizient ist, musst du zureuck zum
letzten Meilenstein.
ES> Optimierungen, die weiter oben nicht wieder Aufwand
ES> verursachen wuerden, sparen tatsaechlich Geld bzw. Zeit.
ES> Deshalb nimmt man in der Praxis eben lieber einen P150 fuer
ES> das Programm, als ein Team von 3 Entwicklern Optimierungen
ES> einbauen zu lassen, die dann das Upgraden auf die naechste
ES> Version erschweren oder wieder rausgeschmissen werden
ES> muessen.
Kommt immer drauf an. Ein PC erzeugt oberflaechlich gesehen keine
Produktionskosten, ab Midrange schon. Und wenn dein Programm 10
Sekunden pro Transaktion zuviel braucht, kannst du in grossen
Firmen ganz schoen viele teure Sachbearbeiterstunden
verschleudern.
ES> Der groessere Rechner ist z.B. bei kaufmaennischen
ES> Systemen meist ziemlich irrelevant. Erlaubt sind natuerlich
ES> algorithmische Optimierungen (z.B. der Einsatz des
ES> Bresenham-Algorithmusses anstatt einen Kreis mit
ES> Fliesskomma-Trigonometrie zu berechnen oder so). Aber
ES> Optimierungen der Marke "Bit-Knipserei! sind nicht nur
ES> unnoetig, sondern meist auch verboten.
Das ist wahr. Niemand wird einen Bubblesort optimieren wollen.
Der geeignete Algorhythmus machts. Und den sollte man schon in
der Desgin Phase im Auge haben.
Unter dieser Argumentation ist ein OS natuerlich genausowenig
eine Endlosschleife, denn aus OSe muessen terminierbar sein...
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.
Die hat er bei einem Betriebssystem selbstverstaendlich auch.
Oder was denkst Du macht ein Betriebssystemscheduler, wenn er
die Maschine sauber runterfahren moechte? !MachinePoweredOff
ist eben nicht die Abbrufbedingung, weil es so nicht
formulierbar ist.
Beide Scheduler (Eventscheduler in einer Anwendung und
Programmscheduler in einem Betriebssystem) sind Verteiler fuer
Ereignisse. Manche sind spezialisierter
(Betriebssystemscheduler verteilt Timerevents), andere
allgemeiner.
Das Ganze ("Betriebssysteme sind Endlosschleifen und ein
Spezialfall") ist ein furchtbares Missverstaendnis zwischen
zwei Zweigen der Informatik. Das faengt schon damit an, dass
Anwendungsprogramme als ein Spezialfall gesehen werden, der sie
nicht sind. Ein Anwendungsprogramm ist ein Unterprogramm des
Betriebssystems. Bei einigen Systemen muss das
Anwendungsunterprogramm mit einer Nichtstandard-Callsequence
aufgerufen werden. Auf der anderen Seite kenne ich auch
Betriebssysteme, bei denen die Anwendung tatsaechlich eine
normale Callsequence fuer Unterprogramme beim Aufruf bekommt.
Der einzige Spezialfall der in jedem Fall bleibt, ist die
Tatsache, dass es sich bei der Anwendung um eine dynamisch
geladene und gebundene Unterfunktion handelt. Das hat aber im
Prinzip keine Auswirkungen auf irgendwelche Korrektheits- oder
Beweisbarkeitsbetrachtungen.
Wenn Du eine Funktion angeben moechtest, die Dir eine
Eventschleife berechnet, dann bekommst Du fuer beide
Schedulerfaelle etwas, das im Prinzip unendliche Datenstroeme
(von Eventtypen) als Eingabeparameter hat und das einen
unendlichen Ausgabestrom als Ausgabeparameter berechnet. Da
Funktionen im allgemeinen ihre Ergebnisse erst dann liefern,
wenn sie ihre Eingabe komplett erhalten haben, ist es bei
Schedulern etwas muehsam, auf die Ergebnisse (unendlich lange)
zu warten.
Das kann man formal relativ leicht erschlagen, indem man die
Funktion lazy evaluieren laesst. Sie entnimmt ihrem Datenstrom
einzelne Eingabeelemente, wendet ihre Algorithmen darauf an und
liefert dann einzelne Elemente fuer den Ausgabestrom. Der
Korrektheitsbeweis beschaeftigt sich dann mit den Elementen und
kann die Unendlichkeit erst einmal ignorieren. Er kann
ausserdem noch Terminierungsbedingungen angeben ("Wenn jemals
das Eingabeelement ... geliefert wird, wird die Funktion
terminieren/einen definierten Endzustand erreichen/keine
weiteren Eingabeelemente mehr annehmen.") und ist damit im
Prinzip abgeschlossen. Er liefert im Gegensatz zum normalen
Korrektheitsbeweis kein einfaches "Ja" oder "Nein", sondern
eine Bedingung als Ergebnis, aber das ist fuer alle praktischen
Zwecke ausreichend.
Und ja, das Verfahren ist auf Betriebssysteme und Anwendungen
gleichermassen anwendbar. Das liegt eben daran, dass
Betriebssysteme keine Sonderfaelle sind.
Zum !MachinePoweredOff noch einmal: Selbstverstaendlich kannst
Du in Anwendungen Deinen Scheduler so programmieren
while (!ende) {
m = GetMessage(&queue);
switch (m->type) {
case ...
break;
case M_QUIT:
ende=true
break;
}
}
oder Du kannst ihn so programmieren:
while(1) {
m = getMessage(&queue);
switch (m->type) {
case ...
break;
case M_QUIT:
exit(0);
break;
}
}
Letztendlich ist das wieder nur eine zusaetzliche semantisch
neutrale Transformation auf Code, der von demselben Modell
generiert wird (das implizite exit() am Ende wird in die
Schleife, den switch und in die Teilbedingung reingezogen und
dadurch ist es moeglich, die Schleifenbedingung zu
eliminieren).
Das erste Beispiel ist das, was Du bei einem
Anwendungsdesignmechanismus unmittelbar erhalten wuerdest. Das
zweite Beispiel ist aus dem ersten durch die besagte
Transformation entstanden. Es ist der Code, den Du bekommst,
wenn Dir die Schleife und die Bedingungen vorgegeben sind (z.B.
durch ein Application Framework) und Du nur noch die case-Slots
des switch() ausfuellst. Es ist auch der Code, den Du bekommst,
wenn Dir das Framework eines Betriebssystems vorgegeben ist und
Du nur noch einen syscall-Slot mit einem "sys_halt()" oder
ausfuellst, nur dass dort eben statt "exit(0)" eine
Assembleranweisung "cli; hlt" oder "cli; l: jmp l" steht.
SO> Nein, das stimmt natuerlich nicht.
Nun, die Diskussion werde ich hier nicht mehr weiter fuehren, denn sie ist
unsinnig, solange einigen die Strukturen, die der Diskussion zugrunde liegen,
nicht vollkommen klar sind. Und ich habe den Eindruck, dass viele Programmierer
die strukturierte Programmierung nicht richtig verstanden haben und meinen,
Pascal sei strukturiert.
SO> Ob etwas _sinnvoll_ ist,
SO> kann mit mathematischen Mitteln ganz sicher nicht bewiesen
SO> werden.
Nun, man kann durchaus Aufwandsbetrachtungen anstellen, was in dem Fall auch
gemacht wurde.
SO> Du bringst da etwas durcheinander: Natuerlich ist
SO> es immer moeglich, goto-Anweisungen _irgendwie_ (ja, sogar
SO> mittels allgemeingueltiger Verfahren) zu eliminieren, aber
SO> dass die Struktur dadurch immer _besser_ wird ist ganz ein-
SO> fach Unsinn. Gegenbeispiele habe ich bereits genannt.
Nun ja, also die Beispiele, die bei mir ankamen, liessen sich tatsaechlich
besser strukturieren. Bessere Struktur bedeutet nicht immer unkomplizierter
oder kuerzer. Struktur heisst unter anderem z.B., einfache und modulare
Bauweise mit leichter Erweiterbarkeit, Redundanzfreiheit (eine Information
steht nur einmal im Quellcode) und ein konsistentesSchema des Logik-Aufbaus.
Die Redundanzfreiheit und das konsistente Aufbau-Schema werden durch break,
goto, continue usw. auf jeden Fall verletzt (Redundanzfreiheit bedeutet z.B.
indirekt auch one-entry-one-exit. Und das ist durch einen Sprung aus einem
Block heraus nicht mehr gegeben. Auch das Ende eines Blockes ist eine
Information).
SO>> Es ist nicht damit getan, sich immer nur auf eine gute
SO>> Programmstruktur zu berufen und dabei das Ziel aus den
SO>> Augen zu verlieren.
Nur mit guter Strukturierung im Programm wirst du dein Ziel auf Dauer
ueberhaupt im Auge behalten koennen.
SO>> In zeit- oder speicherkritischen
SO>> Situationen kann es durchaus eine Menge ausmachen, wenn
SO>> ein Funktionsaufruf mehr oder weniger in einer Schleife
SO>> steckt.
Also, solche Situationen sind mir in 8 Jahren professioneller
Programmiererfahrung, teilweise Datenbank-Bereich, aber auch technischer
Bereich (CAD) vielleicht 2 mal in einer Assembler-Routine untergekommen. Und
das ist seit den letzten Prozessorgenerationen auch noch seltener geworden. Und
fast jedesmal hat sich der Strukturfehler dann einige Zeit spaeter
fuerchterlich geraecht. Viel mehr, als wenn man etwas mehr Power oder Speicher
reingesteckt haette.
SO> Ich nicht. Die Zeiten, in denen ich laut "Assembler" gerufen
SO> habe, wenn ich etwas schneller und/oder kleiner hinbekommen
SO> wollte, sind schon lange vorbei. Heutzutage ist das auch nicht
SO> mehr sinnvoll, da moderne Hochsprachencompiler oft ebensoguten
SO> Code erzeugen wie handoptimierte Assemblerquelltexte. Man muss
SO> als Programmierer nur geschickt genug programmieren, um dem
SO> Compiler solche Optimierungen zu ermoeglichen. Durch die Ein-
SO> fuehrung zahlreicher Zusatzvariablen fuer bedingte Abbrueche
SO> oder durch die Aufteilung vieler kleiner Aktionen auf mehrere
SO> Funktionen wird eine solche Optimierung zunichte gemacht.
Im Gegentum, ein guter Compiler erkennt sowas und kann es erheblich schoener
optimieren. Da faellt der Verlust dann noch weniger auf.
SO> Es gibt grundsaetzlich keine All-
SO> zweckmethode, die _immer_ optimal ist.
Nur gibt es kaum noch Probleme, die sich mit der Nicht-Allzweck-Methode
sinnvoll loesen lassen. Und das werden auch immer weniger. Je komplexer
Software wird, um so weniger kannst du sowas ueberhaupt einsetzen.
SO> Blickwinkel zu sehr ein: Ich rede hier nicht nur von Firmen, die
SO> mehrere Tausende Mark aus dem Hut zaubern koennen, um in Hard-
SO> und Software zu installieren sondern auch vom Otto-Normal-Pro-
SO> grammierer und -Anwender. Die wollen auch irgendwo bleiben, und
SO> ich persoenlich sehe es langsam nicht mehr ein, andauernd teures
SO> Geld fuer immer bessere Hardware auszugeben, weil ein paar grosse
SO> Softwarehaeuser schlechte Software zum Weltstandard erklaeren.
Nun, du brauchst aber als Privatperson auch kaum derart Zeitkritische
Anwendungen (ausser Spielen vielleicht, aber die werden inzwischen eh meist mit
Autorensystemen entwickelt und haben mit Programmierung recht wenig zu tun).
Fuer die Standard-Anwendungen, die Otto-Normal-User faehrt, sind laengst
brauchbare Pakete da, und komplizierte mathematische Berechnungen oder
aehnliches sind fuer solche Leute eh nur Spielerei, die niemand wirklich
interessiert.
SO> Eben. Und das ist es, was ich allem voran bemaengele. Ich habe
SO> schon einige sogenannte "professionelle" Programme gesehen, die
SO> alles andere als professionell programmiert waren.
Nun, es gibt ueberall schlechte und gute Produkte. Aber du wirst wenn du mal
genauer hinsiehst feststellen, dass die Programme umso schlechter sind, je mehr
sie die Strukturregeln verletzen.
ES>> 99% aller GOTO's, die ich bisher sah, kamen eindeutig von
ES>> der Faulheit der jeweiligen Programmierer oder aud mangeln-
ES>> dem Strukturverstaendnis bzw. Designfehlern.
SO> Ein Programm, auf das diese Aussage sicherlich voll und ganz
SO> zutrifft, ist Binkley Term. Aber die Tatsache, dass es schlechte
SO> Beispiele fuer den Einsatz von "goto" gibt, fuehrt doch nicht
SO> automatisch zu der Interpretation, dass e" generell Unsinn ist.
Nicht automatisch. Aber im Zusammenhang mit dem Beweis, dass es unnoetig ist
und mit der Erkenntnis, dass es unabsehbare Folgen bzw. Probleme aufwerfen kann
(insbesondere die Spaetfolgen!).
SO> Das mag fuer grosse Firmen gelten, die ein entsprechendes Budget
SO> zur Verfuegung haben. Aber die Welt besteht nicht nur aus solchen Firmen.
Nun, andere Leute entwickeln aber kaum grosse Anwendungen, die jahrelang
gewartet werden muessen bzw. wo es aufs Geld ankommt. Die arbeiten auch selten
mit CASE-Methoden, sondern VHIDT.
SO> Vielleicht solltest Du einmal nicht nur den Entwickler sehen
SO> sondern auch den Anwender.
Im Endeffekt ist diese Sichtweise aber auch fuer den Anwender besser, auf den
keine Folgeaufwendungen zukommen, die er noch gar nicht absehen kann.
SO> Und darum geht es in den Anwednungbereichen, an die ich denke,
SO> eben nicht. Ich spreche zum Beispiel von langwierigen Rechen-
SO> operationen oder umfangreichen Datenbankzugriffen, von opti-
SO> mierten Zeichenoperationen, usw...
Also, wenn du dir keine 8 MB mehr Speicher leisten kannst, kannst du dir auch
keine derartigen Anwendungen leisten. Auch Software kostet Geld! Allein die
Datenbankengine, die du fuer das, was du schreibst, brauchst, kostet ein
Vielfaches des Speichers.
SO> Das stimmt natuerlich, aendert aber nichts an der Tatsache,
SO> dass auch heute noch Anwendungsgebiete fuer Assembler exi-
SO> stieren. Ich denke da nur an die (mir so verhasste) Spiele-
SO> programmierung unter MS-DOS.
Das ist keine Programmierung, sondern Kurpfuscherei. Mit Software-Entwicklung
hat das herzlich wenig zu tun. Ausserdem verwenden die meisten Spielehersteller
inzwischen spezielle Autorensysteme, die kaum noch Programmierung aufkommen
lassen. Z.B. gibt es nur zwei oder drei verschiedene 3D-Grafikengines, die zur
Zeit in unterschiedlichste Spiele eingebaut werden.
03 Aug 96 22:27, Erhard Schwenk wrote to Kristian =?ISO-8859-1?Q?K=F6hntopp?:
[...]
ES> Strenggenommen ist sogar die BS-Schleife keine Endlosschleife, denn
ES> sie wird durch das Ausschalten des Rechners beendet. Aber die
ES> Konstruktion while (!MachinePoweredOff) ... waere wohl etwas sinnlos,
ES> zumal jedem wohl klar ist, dass auf ner ausgeschalteten Maschine kein
ES> Programm laeuft.
[...]
Zumal jedem klar sein duerfte, dass es derart streng genommen sowas wie eine
Endlosschleife gar nicht gibt (irgendwann -- und wenn's in ein paar Milliarden
Jahren ist -- wird auch die hartnaeckigste Endlosschleife mal beendet. ;-) ).
ES> Wenn du
ES> deine Schleifen aber mal ein bisschen mit Leben fuellst, wirst du
schnell
ES> sehen, dass deine Methode recht gefaehrlich werden kann.
Wieso? Wenn man dieses Konzept strikt fuer "Abbruch bei Fehlerbedingungen"
benutzt und das entsprechend (durch Bezeichnung des Labels) kenntlich
macht,
ist das IMHO uebersichtlicher als mit Flags rumzuackern. Die Wartbarkeit
ist
gegenueber dem gehaeuften Einsatz eines Fehlerflags oder geschachtelten
if-
Abfragen IMHO auch besser.
ES> Uebrigens: das
ES> Goto ist auch nicht ganz so sauber wie es aussieht, denn es erzeugt
noch
ES> ne Menge Stack-Aufraeumarbeiten.
Wofuer sollen die denn benoetigt werden? Wenn ueberhaupt, ist das
compilerabhaengig.
Ciao
Hermann
--- Eine ganze MsgBase dank XP-Repair!
* Origin: Reality corrupted - Reboot universe? (Y/N) (2:2454/130.10)
Am 06.08.96 schrieb Kristian =?ISO-8859-1?Q?K=F6hntopp?:
K> Unter dieser Argumentation ist ein OS natuerlich genausowenig
K> eine Endlosschleife, denn aus OSe muessen terminierbar sein...
Ein OS terminiert genau dann, wenn man den Saft abdreht. Ansonsten laeuft der
Prozessor munter weiter.
Servus, Michael.
--- FleetStreet 1.17+
* Origin: FleetStreet - where I want to go today (2:2490/2520.17)
ES>> Strenggenommen ist sogar die BS-Schleife keine Endlosschleife, denn sie
ES>> wird durch das Ausschalten des Rechners beendet. Aber die Konstruktion
ES>> while (!MachinePoweredOff) ... waere wohl etwas sinnlos, zumal jedem wohl
ES>> klar ist, dass auf ner ausgeschalteten Maschine kein Programm laeuft.
MM> Zumal jedem klar sein duerfte, dass es derart streng genommen sowas wie
MM> eine Endlosschleife gar nicht gibt (irgendwann -- und wenn's in ein paar
MM> Milliarden Jahren ist -- wird auch die hartnaeckigste Endlosschleife mal
MM> beendet. ;-) ).
Richtig. Aber nichtsdestotrotz ist es immer besser, die Abbruchbedingungen auch
sauber hinzuschreiben. Auf jeden Fall besser, als dann in der Schleife ein
break zu setzen.
MfG, Erhard.
HJH> Wofuer sollen die denn benoetigt werden? Wenn ueberhaupt, ist das
HJH> compilerabhaengig.
z.B. um lokale Block-Variablen oder Ruecksprungadressen von Schleifen wieder
vom Stack zu holen. Schau dir mal den Code an, den z.B. eine For-Schleife mit 3
Verschachtelungstiefen erzeugt. Da wird der Schleifenzaehler oft auf den Stack
gelegt (was ja auch sinnvoll ist).
Und nun?
- Marcus
MH> Ein OS terminiert genau dann, wenn man den Saft abdreht. Ansonsten laeuft
der
MH> Prozessor munter weiter.
Unix und auch mein Mac (ja ich glaube sogar Windows) terminieren sich, was
heißen soll, sie räumen ihre Resourcen auf.
Was der Prozessor danach macht, ist eigentlich egal. Aber schon der Z80 hatte
einen 'HALT'-Befehl, aus dem er nur mit einem Interupt aufgeweckt werden
konnte.
Ciao, Siggi.
>Nun ja, das kommt auf das Programm an. Unter Umstaenden darf es z.B. durchaus
>zusaetzliche Debugging-Informationen liefern oder es werden bestimmte
>Nebeneffekte in Kauf genommen, wenn sie nicht wehtun und sonst nur den Aufwand
>erhoehen wuerden.
Aehm, Du warst derjenige, der hier mit Strukturierung,
Modellbildung, Korrektheit und Beweisverpflichtung angekommen
ist, da erinnere ich mich doch richtig, oder? Wenn man sowieso
schon dabei ist, diesen Formalapparat in Bewegung zu setzen,
dann kann man ihn auch zu Ende bringen und so simple Dinge wie
Funktionserweiterung (von partiellen auf totale Funktionen) und
Kontexterweiterung (zur Vermeidung von Seiteneffekten)
durchfuehren (*1). Wenn der ganze Formalapparat sowieso schon
laeuft, ist das auch kein wirklich zusaetzlicher Aufwand mehr.
>Das ist natuerlich korrekt. Mit der Aufzaehlung war aber die Prioritaet der
>einzelnen Kriterien bei der Implementierung gemeint. Und hier ist Effizienz
>tatsaechlich erst _nach_ Wartbarkeit bzw. den 6 anderen Kriterien ein
Argument.
Ich kenne Kunden, die sehen das anders. :-)
>Eben. Den Bubble-sort dann wegen der Geschwindigkeit in Assembler zu
>implementieren, ist mit Verlaub Schwachsinn.
Ja.
Kristian
(*1) Eine Ausgabe auf dem Bildschirm ist kein Seiteneffekt in
Deinem Programm, wenn der Bildschirm eine Variable in
Deinem Modell ist.
--
Kristian Koehntopp, Wassilystrasse 30, 24113 Kiel, +49 431 688897
"Plan:
World domination. Fast."
-- "finger torv...@linux.cs.helsinki.fi", 7. May 1996