Discussion:
Gleicheitszeichen mal andersherum
(zu alt für eine Antwort)
Rainer Weikusat
2017-03-03 22:18:07 UTC
Permalink
In einem Anfall von Uebermut habe ich beschlossen, endlich mal ein
ueberfluessiges caddr_t <=> 'generic pointer' in dem racoon-fork, an dem
ich so rumentwickle, durch einen vernuenftigen Zeigertyp zu
ersetzen. Entschlossen habe ich mich fuer 'unsigned char *' weil ich
keine Lust habe, 50% des zu erwartenden Wertebereiches in einer
Debugger-Ausgabe mit 'seltsamen Strichlein' garniert zu
sehen. Unmittelbares Resultat davon waren eine Menge "Vorzeichenloser
Typ benutzt ! Pure fucking Armageddon !!1"-Warnungen, ueber die sich
Helmut vor einiger Zeit bereits mokiert hatte. Ein paar davon habe ich
via casts eliminiert bevor mir das zu bloed wurde und ich einfach
-Wno-pointer-sign zu den 'default compiler flags' hinzugefuegt habe.

Bei der Gelegenheit habe ich dort ein -Wno-unused entdeckt. Im Gegensatz
zu "Hoellische Verderbtheit erkannt ! Mag keine Vorzeichen !!1" sind
diese Warnungen allerdings normalerweise sinnvoll, denn unbenutzter Code
sieht fuer's blosse Auge genauso wie benutzter aus, auch wenn "Ach was,
funzt doch!"-Typen sie nicht unbedingt sehen moechten. Dieses foederte
folgenden, sehr realen Fehler zu Tage:

while (p) {
next = p->next;

close(p->sock);
p->sock == -1;

(wahrscheinlich von mir)
Rainer Weikusat
2017-03-03 23:05:16 UTC
Permalink
Rainer Weikusat <***@talktalk.net> writes:

[-Wpointer-sign Quatsch]


[-Wused nuetzelich]
Post by Rainer Weikusat
while (p) {
next = p->next;
close(p->sock);
p->sock == -1;
Davon hat der Compiler in den ca 72,500 Zeilen Code, um die es hier
geht, mittlerweile noch eines gefunden. Ein exzellentes Beispiel fuer
"Compiler findet reale Fehler nicht" weil jemand aus reiner Faulheit
eine bestimmte Sorte Warnungen unterbunden hatte, waehrend derselbe
jemand (oder dieselben jemande) brav an allen Stellen an denen die garantiert
bedeutungsfreie Vorzeichenwarnung auftrat, einen cast eingefuegt hatte.
Helmut Schellong
2017-03-05 11:05:05 UTC
Permalink
Post by Rainer Weikusat
[-Wpointer-sign Quatsch]
[-Wused nuetzelich]
Post by Rainer Weikusat
while (p) {
next = p->next;
close(p->sock);
p->sock == -1;
Davon hat der Compiler in den ca 72,500 Zeilen Code, um die es hier
geht, mittlerweile noch eines gefunden. Ein exzellentes Beispiel fuer
"Compiler findet reale Fehler nicht" weil jemand aus reiner Faulheit
eine bestimmte Sorte Warnungen unterbunden hatte, waehrend derselbe
jemand (oder dieselben jemande) brav an allen Stellen an denen die garantiert
bedeutungsfreie Vorzeichenwarnung auftrat, einen cast eingefuegt hatte.
Im Laufe von etwa 20 Jahren habe ich diesbezüglich mehrere verschiedene
Verhaltensweisen des gcc festgestellt.
Genau das ist das Ärgerliche.
Casts hatte ich nie verwendet.

Seit einiger Zeit verwende ich:
#define byte char
-funsigned-char


Oben 'while (p) {' ist etwas ungewöhnlich.
--
Mit freundlichen Grüßen
Helmut Schellong ***@schellong.biz
www.schellong.de www.schellong.com www.schellong.biz
http://www.schellong.de/c.htm
Patrick.Schluter
2017-03-05 12:16:35 UTC
Permalink
Post by Helmut Schellong
Post by Rainer Weikusat
[-Wpointer-sign Quatsch]
[-Wused nuetzelich]
Post by Rainer Weikusat
while (p) {
next = p->next;
close(p->sock);
p->sock == -1;
Davon hat der Compiler in den ca 72,500 Zeilen Code, um die es hier
geht, mittlerweile noch eines gefunden. Ein exzellentes Beispiel fuer
"Compiler findet reale Fehler nicht" weil jemand aus reiner Faulheit
eine bestimmte Sorte Warnungen unterbunden hatte, waehrend derselbe
jemand (oder dieselben jemande) brav an allen Stellen an denen die garantiert
bedeutungsfreie Vorzeichenwarnung auftrat, einen cast eingefuegt hatte.
Im Laufe von etwa 20 Jahren habe ich diesbezüglich mehrere verschiedene
Verhaltensweisen des gcc festgestellt.
Genau das ist das Ärgerliche.
Casts hatte ich nie verwendet.
#define byte char
-funsigned-char
Oben 'while (p) {' ist etwas ungewöhnlich.
Nö. Ziemlich verbreitet. Etwa weniger als (p != NULL) aber dennoch nicht
selten. Ein NULL Pointer gilt als unwahr und es spart viel Tipparbeit
und is auch leicht zu lesen.
for(p=head; p; p=p->next) ist eine schöne idiomatische Listenschleife.

Letzendlich ist es aber Geschmacksache und jeder kann es halten wie es
ihm besser gefällt (und auch deshalb war ich auch ziemlich verärgert das
clang-llvm (oder war es gcc 6.2 weiss jetzt nicht mehr 100%) ein warning
bei solch einem Ausdruck bringt (implicit bool cast).
Helmut Schellong
2017-03-05 20:30:21 UTC
Permalink
Post by Patrick.Schluter
Post by Helmut Schellong
Oben 'while (p) {' ist etwas ungewöhnlich.
Nö. Ziemlich verbreitet. Etwa weniger als (p != NULL) aber dennoch nicht
selten. Ein NULL Pointer gilt als unwahr und es spart viel Tipparbeit und is
auch leicht zu lesen.
for(p=head; p; p=p->next) ist eine schöne idiomatische Listenschleife.
Ich verwandte das Wort 'etwas', gleichbedeutend mit 'ein bißchen',
'ein klein wenig', etc.

Und ich fand genau 'while (p) {' etwas ungewöhnlich (im Zusammenhang).
Also genau: 'while (p) {', und nichts anderes.

Ich verwende (vorzugsweise) schon immer 'if (p)' statt 'if (p!=NULL)'.
Post by Patrick.Schluter
Letzendlich ist es aber Geschmacksache und jeder kann es halten wie es ihm
besser gefällt (und auch deshalb war ich auch ziemlich verärgert das
clang-llvm (oder war es gcc 6.2 weiss jetzt nicht mehr 100%) ein warning bei
solch einem Ausdruck bringt (implicit bool cast).
Solch ein Ausdruck ist C-typisch und gar nicht ungewöhnlich.
Eine Warnung ist nicht schlimm, aber doof.

Was ist denn, wenn man 'if (p+0)' formuliert?
--
Mit freundlichen Grüßen
Helmut Schellong ***@schellong.biz
www.schellong.de www.schellong.com www.schellong.biz
http://www.schellong.de/c.htm
Claus Reibenstein
2017-03-05 21:46:12 UTC
Permalink
Post by Helmut Schellong
Post by Patrick.Schluter
Post by Helmut Schellong
Oben 'while (p) {' ist etwas ungewöhnlich.
Nö. Ziemlich verbreitet. Etwa weniger als (p != NULL) aber dennoch nicht
selten. Ein NULL Pointer gilt als unwahr und es spart viel Tipparbeit und is
auch leicht zu lesen.
for(p=head; p; p=p->next) ist eine schöne idiomatische Listenschleife.
Ich verwandte das Wort 'etwas', gleichbedeutend mit 'ein bißchen',
'ein klein wenig', etc.
So viel Deutsch kann ich gerade noch.
Post by Helmut Schellong
Und ich fand genau 'while (p) {' etwas ungewöhnlich (im Zusammenhang).
Also genau: 'while (p) {', und nichts anderes.
Ich verwende (vorzugsweise) schon immer 'if (p)' statt 'if (p!=NULL)'.
Dann verstehe ich erst recht nicht, was daran ungewöhnlich sein soll.
Post by Helmut Schellong
Was ist denn, wenn man 'if (p+0)' formuliert?
Was soll denn dann sein?

Gruß
Claus
Helmut Schellong
2017-03-06 09:56:38 UTC
Permalink
Post by Claus Reibenstein
Post by Helmut Schellong
Was ist denn, wenn man 'if (p+0)' formuliert?
Was soll denn dann sein?
Ob dann die Warnung immer noch kommt.
--
Mit freundlichen Grüßen
Helmut Schellong ***@schellong.biz
www.schellong.de www.schellong.com www.schellong.biz
http://www.schellong.de/c.htm
Rainer Weikusat
2017-03-06 11:41:38 UTC
Permalink
Post by Helmut Schellong
Post by Claus Reibenstein
Post by Helmut Schellong
Was ist denn, wenn man 'if (p+0)' formuliert?
Was soll denn dann sein?
Ob dann die Warnung immer noch kommt.
Moeglicherweise kommt dann etwas spaeter eine unangenehme Ueberraschung:
Arithmetik mit ungueltigen Zeigern ist undefiniert, hier koennte der
Compiler(-Entwickler) also "annehmen", dass die Bedingung immer wahr
sein muss, und den Code unter den Tisch fallen lassen.
Helmut Schellong
2017-03-06 12:45:52 UTC
Permalink
Post by Rainer Weikusat
Post by Helmut Schellong
Post by Claus Reibenstein
Post by Helmut Schellong
Was ist denn, wenn man 'if (p+0)' formuliert?
Was soll denn dann sein?
Ob dann die Warnung immer noch kommt.
Arithmetik mit ungueltigen Zeigern ist undefiniert, hier koennte der
Compiler(-Entwickler) also "annehmen", dass die Bedingung immer wahr
sein muss, und den Code unter den Tisch fallen lassen.
sizeof("abc")
sizeof("abc"+0)

Es kann verschiedentlich '+0' verwendet werden, um einen
Pointer-Kontext zu erzwingen.
--
Mit freundlichen Grüßen
Helmut Schellong ***@schellong.biz
www.schellong.de www.schellong.com www.schellong.biz
http://www.schellong.de/c.htm
Rainer Weikusat
2017-03-06 15:25:36 UTC
Permalink
Post by Helmut Schellong
Post by Rainer Weikusat
Post by Helmut Schellong
Post by Claus Reibenstein
Post by Helmut Schellong
Was ist denn, wenn man 'if (p+0)' formuliert?
Was soll denn dann sein?
Ob dann die Warnung immer noch kommt.
Arithmetik mit ungueltigen Zeigern ist undefiniert,
[...]
Post by Helmut Schellong
sizeof("abc")
sizeof("abc"+0)
Es kann verschiedentlich '+0' verwendet werden, um einen
Pointer-Kontext zu erzwingen.
Vollkommen andere Situation: "abc" ist ein String-Literal, dh ein
namenloses char-Array. Benutzt man ein solches Array als Argument von +
wird es in einen Zeiger auf das erste Element
konvertiert. Zeigerarithmetik ist fuer Zeiger in ein Array definiert,
Probleme mit + gibt es hier also keine.

Aber if (p) ueberprueft ob p ein gueltiger Zeiger ist. Falls das nicht
der Fall war, sind arithmetische Operationen mit diesem Zeiger nicht
definiert. Folglicherweise gibt es fuer

if (p + 0)

zwei Moeglichkeiten:

1) Immer wahr.

2) Undefinitertes Verhalten.

gcc ist 'beruechtigt' (ob berechtigt weiss ich nicht) dafuer,
Gueltigkeitstests von Zeigern wegzuoptimieren falls es Grund zu der
Annahme gibt, dass der Zeiger nicht ungueltig sein kann, weil er bereits
in einer Weise benutzt wurde, die nur fuer gueltige Zeiger definitiertes
Verhalten hat.
Hermann Riemann
2017-03-07 07:27:24 UTC
Permalink
Post by Helmut Schellong
Post by Helmut Schellong
Oben 'while (p) {' ist etwas ungewöhnlich.
while(p)
Da vermute ich dass da nur den Zahlenwert der Adresse überprüft wird.
Solange NULL 0 ist, ist das kein Problem.
Post by Helmut Schellong
Was ist denn, wenn man 'if (p+0)' formuliert?
pointer + int bedeutet pointer_Wert (=Adresse) + zahl*sizeof(*p)

Also ergibt p+0 wieder p ( Gleicher Typ, gleicher Wert)

Hermann
der seine pointer auf Strukturen, die pointer enthalten
auch mit memset(pointer,'\0',sizeof(*pointer));
initialisiert, und hofft, dass bei gcc .. NULL 0 bleibt.
--
http://www.hermann-riemann.de
Juergen Ilse
2017-03-07 09:20:54 UTC
Permalink
Hallo,
Post by Hermann Riemann
Post by Helmut Schellong
Post by Helmut Schellong
Oben 'while (p) {' ist etwas ungewöhnlich.
while(p)
Da vermute ich dass da nur den Zahlenwert der Adresse überprüft wird.
Solange NULL 0 ist, ist das kein Problem.
Post by Helmut Schellong
Was ist denn, wenn man 'if (p+0)' formuliert?
pointer + int bedeutet pointer_Wert (=Adresse) + zahl*sizeof(*p)
Also ergibt p+0 wieder p ( Gleicher Typ, gleicher Wert)
... solange es kein void pointer ist. Laut aktuellem C-Standard ist das
Verhalten bei pointer-arithmetik mit void pointern IIRC undefiniert.
Es *kann* sein, dass das wie Arthmetik mit Pointer auf char oder unsigned
char behandelt wird (wie es aeltere C-Compiler teils taten), der compiler
duerfte das compilieren auch mit einer Fehlermeldung verweigern, es kann
aber auch ein nicht (oder nur manchmal) lauffaehiges Programm dabei heraus-
kommen (was zwar nicht wuenschenswert waere, aber auch so etwas wuerde nicht
gegen den Sprachstandard verstossen, weil pointer arithmetik mit void*
schlicht vom Sprachstandard in keienr Weise gedeckt ist, genau genommen
noch nicht einmal das "+ 0").

Tschuess,
Juergen Ilse (***@usenet-verwaltung.de)
Helmut Schellong
2017-03-07 11:45:33 UTC
Permalink
Post by Hermann Riemann
Post by Helmut Schellong
Was ist denn, wenn man 'if (p+0)' formuliert?
pointer + int bedeutet pointer_Wert (=Adresse) + zahl*sizeof(*p)
Also ergibt p+0 wieder p ( Gleicher Typ, gleicher Wert)
Ich meine hier subtiles Warnungs-Verhalten von Compilern.

Der Ursprung (Patrick Schluter):
===================================================================
und auch deshalb war ich auch ziemlich verärgert das clang-llvm
(oder war es gcc 6.2 weiss jetzt nicht mehr 100%) ein warning
bei solch einem Ausdruck bringt (implicit bool cast).
===================================================================

Also solch eine Warnung bei 'if (p)'.
Und ich fragte dann, ob bei 'if (p+0)'
immer noch diese Warnung kommt.

Nur, der bisherige Thread, die Ursprünge, werden im Thread
zusehends vergessen.
--
Mit freundlichen Grüßen
Helmut Schellong ***@schellong.biz
www.schellong.de www.schellong.com www.schellong.biz
http://www.schellong.de/c.htm
Rainer Weikusat
2017-03-07 13:05:29 UTC
Permalink
Post by Helmut Schellong
Post by Hermann Riemann
Post by Helmut Schellong
Was ist denn, wenn man 'if (p+0)' formuliert?
pointer + int bedeutet pointer_Wert (=Adresse) + zahl*sizeof(*p)
Also ergibt p+0 wieder p ( Gleicher Typ, gleicher Wert)
Ich meine hier subtiles Warnungs-Verhalten von Compilern.
===================================================================
und auch deshalb war ich auch ziemlich verärgert das clang-llvm
(oder war es gcc 6.2 weiss jetzt nicht mehr 100%) ein warning
bei solch einem Ausdruck bringt (implicit bool cast).
===================================================================
Also solch eine Warnung bei 'if (p)'.
Und ich fragte dann, ob bei 'if (p+0)'
immer noch diese Warnung kommt.
if (p)

ist ein korrekter Nullzeiger-Test.

if (p + 0)

ist wahlweise unsinnig (p != 0) oder undefiniert (p == 0).
Patrick.Schluter
2017-03-07 20:55:29 UTC
Permalink
Post by Helmut Schellong
Post by Hermann Riemann
Post by Helmut Schellong
Was ist denn, wenn man 'if (p+0)' formuliert?
pointer + int bedeutet pointer_Wert (=Adresse) + zahl*sizeof(*p)
Also ergibt p+0 wieder p ( Gleicher Typ, gleicher Wert)
Ich meine hier subtiles Warnungs-Verhalten von Compilern.
===================================================================
und auch deshalb war ich auch ziemlich verärgert das clang-llvm
(oder war es gcc 6.2 weiss jetzt nicht mehr 100%) ein warning
bei solch einem Ausdruck bringt (implicit bool cast).
===================================================================
Ich habe es mir wieder angeschaut. Das Warning kam bei clang-llvm vor
und wird nur generiert wenn die Warningstufe -Weverything eingestellt
wird. Es ist keine gute Idee permanent mit -Weverything zu Kompilieren
weil sehr viele der Warnings die das kommen sind völlig unnötig. Diese
implicit-bool-conversion Warnung gehört meines Erachtens dazu.
Post by Helmut Schellong
Also solch eine Warnung bei 'if (p)'.
Und ich fragte dann, ob bei 'if (p+0)'
Ich hab's zwar jetzt nicht getestet dürfte aber genauso warnen. Die
warnung dient um vor "vergessene" Vergleichszeichen zu warnen. Was in
Java durch einen "harten Boolean Typ"* erzwungen wird.

* mit hartem Typ nenne ich einen Typ der nur über einen expliciten
Typecast umgewandelt werden kann.
Post by Helmut Schellong
immer noch diese Warnung kommt.
Nur, der bisherige Thread, die Ursprünge, werden im Thread
zusehends vergessen.
Rainer Weikusat
2017-03-07 21:31:49 UTC
Permalink
[...]
Post by Patrick.Schluter
Post by Helmut Schellong
===================================================================
und auch deshalb war ich auch ziemlich verärgert das clang-llvm
(oder war es gcc 6.2 weiss jetzt nicht mehr 100%) ein warning
bei solch einem Ausdruck bringt (implicit bool cast).
===================================================================
'implicit bool cast' ist unter allen Umstaenden Bloedsinn: Ein 'cast'
ist ein Typkonvertierungsoperator den man benutzen muss, falls man eine
Konvertierung wuenscht, die nicht automatich vergenommen wird.
Post by Patrick.Schluter
Post by Helmut Schellong
Also solch eine Warnung bei 'if (p)'.
Und ich fragte dann, ob bei 'if (p+0)'
Ich hab's zwar jetzt nicht getestet dürfte aber genauso warnen. Die
warnung dient um vor "vergessene" Vergleichszeichen zu warnen. Was in
Java durch einen "harten Boolean Typ"* erzwungen wird.
* mit hartem Typ nenne ich einen Typ der nur über einen expliciten
Typecast umgewandelt werden kann.
Soweit es C angeht, ist "implizite Konvertierung nach bool" eine
Wahnvorstellung der LLVM-Entwickler. Sowas gibt es nicht.

if (<expr>) <statement>;

meint '<statement> wird ausgefuehrt falls die Auswertung von <expr>
einen Wert ergab, fuer den != 0 galt'. Als Resultat der Auswertung eines
Vergleichoperators erhaelt man einen int mit Wert 0 oder 1.
Rainer Weikusat
2017-03-07 13:03:05 UTC
Permalink
Post by Hermann Riemann
Post by Helmut Schellong
Post by Helmut Schellong
Oben 'while (p) {' ist etwas ungewöhnlich.
while(p)
Da vermute ich dass da nur den Zahlenwert der Adresse überprüft wird.
Solange NULL 0 ist, ist das kein Problem.
Das ist allerdings nicht der Fall: Sei p ein Zeiger, dann soll eine
Schleife

while (p) { ... }

solange ausgefuehrt werden wie p != 0 wahr ist,

An iteration statement causes a statement called the loop body to be
executed repeatedly until the controlling expression compares
equal to 0.
[6.5.8|4]

Ist p ein Zeiger ist, ist 0 in p != 0 eine Nullzeigerconstante. Hier
wird also 'gueltiger oder ungueltiger Zeiger' ueberprueft, unabhaengig
davon, wie ein gueltiger oder ungueltiger Zeiger konkret repraesentiert
wird.
Post by Hermann Riemann
Post by Helmut Schellong
Was ist denn, wenn man 'if (p+0)' formuliert?
pointer + int bedeutet pointer_Wert (=Adresse) + zahl*sizeof(*p)
Also ergibt p+0 wieder p ( Gleicher Typ, gleicher Wert)
Wie bereits aaO geschrieben: Falls p ein Nullzeiger ist, ist das
Verhalten der Addition undefiniert.

If both the pointer operand and the result point to elements of
the same array object, or one past the last element of the array
object, the evaluation shall not produce an overflow; otherwise,
the behavior is undefined.
[6.5.6|8]

Damit ist die Addition nicht nur sinnlos (arithmetisch weil sich der
Wert nicht aendert, logisch weil sich der Typ auch nicht aendert)
sondern ausserdem riskant.
Hermann Riemann
2017-03-07 13:50:24 UTC
Permalink
Post by Rainer Weikusat
Das ist allerdings nicht der Fall: Sei p ein Zeiger, dann soll eine
Schleife
while (p) { ... }
solange ausgefuehrt werden wie p != 0 wahr ist,
Wenn p ein Zeiger ist und 0 eine Ganzzahl,
wie wird das dann konvertiert?

Bei while (p) würde noch Wert !=0 passen.
Post by Rainer Weikusat
Ist p ein Zeiger ist, ist 0 in p != 0 eine Nullzeigerconstante. Hier
wird also 'gueltiger oder ungueltiger Zeiger' ueberprueft, unabhaengig
davon, wie ein gueltiger oder ungueltiger Zeiger konkret repraesentiert
wird.
Post by Hermann Riemann
Post by Helmut Schellong
Was ist denn, wenn man 'if (p+0)' formuliert?
pointer + int bedeutet pointer_Wert (=Adresse) + zahl*sizeof(*p)
Also ergibt p+0 wieder p ( Gleicher Typ, gleicher Wert)
Hier hätte ich noch p!=void* hinzufügen müssen.
Wenn p z.B. vom Typ int* oder char* ist ..
Post by Rainer Weikusat
Wie bereits aaO geschrieben: Falls p ein Nullzeiger ist, ist das
Verhalten der Addition undefiniert.
Nullzeiger wäre NULL
Post by Rainer Weikusat
Damit ist die Addition nicht nur sinnlos (arithmetisch weil sich der
Wert nicht aendert, logisch weil sich der Typ auch nicht aendert)
sondern ausserdem riskant.
Das alte

while (p) {
next = p->next;

close(p->sock);
p->sock == -1;

könnte mit
p=next;}
enden.

Hermann
dessen
char*feld[]={"anf",..
mit
NULL};
endet, wenn er sich die Länge nicht merken mag.
--
http://www.hermann-riemann.de
Juergen Ilse
2017-03-07 15:13:58 UTC
Permalink
Hallo,
Post by Hermann Riemann
Post by Rainer Weikusat
Das ist allerdings nicht der Fall: Sei p ein Zeiger, dann soll eine
Schleife
while (p) { ... }
solange ausgefuehrt werden wie p != 0 wahr ist,
Wenn p ein Zeiger ist und 0 eine Ganzzahl,
wie wird das dann konvertiert?
Gemaess der Standardvorgaben der Sprache C: Die Ganzzahl 0 wird dann zu einem
Nullpointer des gleichen Typs wie p konverteiert (unabzhaengig davon, wie bei
dieser Implementierung von C nun diese Darstellung des entsprechenden Null-
pointers waere) und dann verglichen. Man sollte uebrigens ggfs. auch NULL
(das Makro) ggfs. zum entsprechenden Pointertyp konverteieren, wenn man sicher
sein will, einen Nullpointer eines entsprechenden Typs zu erhalten, denn laut
Sprachstandard ist der Wert des Makros entweder eine Ganzzahlkonstante mit dem
Wert 0 oder eine solche zu einem void* konvertiert (welche der beiden Moeg-
lichkeiten in der jeweiligen standardkonformen C-Implementierung umgesetzt
wird, schreibt der Sprachstandard *nicht* vor).

Tschuess,
Juergen Ilse (***@usenet-verwaltung.de)
Rainer Weikusat
2017-03-07 15:41:06 UTC
Permalink
Post by Hermann Riemann
Post by Rainer Weikusat
Das ist allerdings nicht der Fall: Sei p ein Zeiger, dann soll eine
Schleife
while (p) { ... }
solange ausgefuehrt werden wie p != 0 wahr ist,
Wenn p ein Zeiger ist und 0 eine Ganzzahl,
wie wird das dann konvertiert?
0 ist eine Nullzeigerkonstante (null pointer constant). Fuer den
Vergleich wird sie in einen Nullzeiger passenden Typs konvertiert.

[if (p + 0)]
Post by Hermann Riemann
Post by Rainer Weikusat
Wie bereits aaO geschrieben: Falls p ein Nullzeiger ist, ist das
Verhalten der Addition undefiniert.
Nullzeiger wäre NULL
NULL ist ein Makro, das zu einer Nullzeigerkonstante expandieren soll,
dh einer 'integer constant expression' mit Wert 0 oder einer solchen,
die nach void * gecasted wurde. ZB

#define NULL ((15 - 15) / (15 - 14))

Einen Nullzeiger erhaelt man, wenn eine Nullzeigerkonstante in einen
Zeigertyp konvertiert wird.
Post by Hermann Riemann
Post by Rainer Weikusat
Damit ist die Addition nicht nur sinnlos (arithmetisch weil sich der
Wert nicht aendert, logisch weil sich der Typ auch nicht aendert)
sondern ausserdem riskant.
Das alte
while (p) {
next = p->next;
close(p->sock);
p->sock == -1;
könnte mit
p=next;}
enden.
Offensichtlich tut es das. Aber den Sinn dieser Bemerkung im gegebenen
Kontext verstehe ich nicht.
Rainer Weikusat
2017-03-05 20:10:42 UTC
Permalink
Post by Helmut Schellong
Post by Rainer Weikusat
[-Wpointer-sign Quatsch]
[-Wused nuetzelich]
Post by Rainer Weikusat
while (p) {
next = p->next;
close(p->sock);
p->sock == -1;
Davon hat der Compiler in den ca 72,500 Zeilen Code, um die es hier
geht, mittlerweile noch eines gefunden. Ein exzellentes Beispiel fuer
"Compiler findet reale Fehler nicht" weil jemand aus reiner Faulheit
eine bestimmte Sorte Warnungen unterbunden hatte, waehrend derselbe
jemand (oder dieselben jemande) brav an allen Stellen an denen die garantiert
bedeutungsfreie Vorzeichenwarnung auftrat, einen cast eingefuegt hatte.
Im Laufe von etwa 20 Jahren habe ich diesbezüglich mehrere verschiedene
Verhaltensweisen des gcc festgestellt.
Genau das ist das Ärgerliche.
Casts hatte ich nie verwendet.
Sind hier auch vollkommen sinnfrei: Falls char * und unsigned char *
unterschiedliche Repraesentationen haetten, wuerde ein cast das Problem
nicht beheben. Wenn man das ernstnaehme, waere die einzige Loesung den
Inhalt des Speicherbereiches, auf den der unsigned char * zeigte, in
eine zu kopieren, auf den ein char * zeigt. Oder - was wohl der Sinn des
ganzen Manoevers ist - auf die Benutzung von Zeigern auf vorzeichenlose
chars ueberhaupt zu verzichten.

[...]
Post by Helmut Schellong
Oben 'while (p) {' ist etwas ungewöhnlich.
Warum das?
Helmut Schellong
2017-03-06 10:10:56 UTC
Permalink
Post by Rainer Weikusat
Post by Helmut Schellong
Post by Rainer Weikusat
while (p) {
next = p->next;
close(p->sock);
p->sock == -1;
Oben 'while (p) {' ist etwas ungewöhnlich.
Warum das?
for (p=sa; p->g; ++p)

for (p=p0; p->nxt; p=p->nxt)


Ich formuliere eher wie vorstehend.
Allein deshalb schrieb ich 'etwas ungewöhnlich'.
'while (p) {' ist _für mich_ etwas ungewöhnlich.

Diese Randbemerkung hätte ich weglassen sollen;
hat nur zur Verwirrung geführt.
--
Mit freundlichen Grüßen
Helmut Schellong ***@schellong.biz
www.schellong.de www.schellong.com www.schellong.biz
http://www.schellong.de/c.htm
Rainer Weikusat
2017-03-09 22:01:31 UTC
Permalink
Post by Helmut Schellong
Post by Rainer Weikusat
Post by Helmut Schellong
Post by Rainer Weikusat
while (p) {
next = p->next;
close(p->sock);
p->sock == -1;
Oben 'while (p) {' ist etwas ungewöhnlich.
Warum das?
for (p=sa; p->g; ++p)
for (p=p0; p->nxt; p=p->nxt)
for (;;;)

ist in C eine Art Compiler-Makro dessen Sinn sich mir vollkommen
verschliesst. Richtige Schleifen habe zB Initialisierungs-Anweisungen,
die so aussehen:

trns = sa->trns;
if (!trns) {
the_trns.enc.type = sa->enctype;
the_trns.enc.len = sa->encklen;
the_trns.hash = sa->hashtype;
the_trns.dhg = sa->dh_group;
the_trns.p = NULL;

trns = &the_trns;
}

t_no = *trns_no;

Selbst wenn man das im ersten Abschnitt von for unterbringen koennte,
sollte man das lieber lassen. Die Baby-Initiasierung und die
Moeglichkeit, dass letzte Statement der Schleife ans Ende ihrer ersten
Zeile zu ziehen ("Wisu denn blus?") machen nur die Bedingung
unkenntlich.
Hermann Riemann
2017-03-10 05:43:18 UTC
Permalink
Post by Rainer Weikusat
for (;;;)
ist in C eine Art Compiler-Makro dessen Sinn sich mir vollkommen
verschliesst.
Ist nur das Gleiche wie:

while(1)
bei der der compiler die irreführende Abfrage wegoptimieren sollte.
Post by Rainer Weikusat
Richtige Schleifen habe zB Initialisierungs-Anweisungen,
label:
mache_nichts();
goto label:

ist doch eine richtige Schleife.
Post by Rainer Weikusat
Selbst wenn man das im ersten Abschnitt von for unterbringen koennte,
sollte man das lieber lassen. Die Baby-Initiasierung und die
Moeglichkeit, dass letzte Statement der Schleife ans Ende ihrer ersten
Zeile zu ziehen ("Wisu denn blus?") machen nur die Bedingung
unkenntlich.
Die meiste meiner Schleifen sehe prinzipiell so aus:

for (int i=0; i<end_wert; i++)

Das halte ich meist für eine bessere Ordnung als irgendwo
im Schleifenrumpf i++ zu "verstecken,
oder bei einer langen Schleife außerhalb des Sichtbereiches
( Papier andere Seite; Bildschirm >=1 Bild blättern. )

Hermann
der vermutet, das jede Ordnung irgendwie nicht passt.
--
http://www.hermann-riemann.de
Rainer Weikusat
2017-03-10 22:11:14 UTC
Permalink
Hermann Riemann <***@hermann-riemann.de> writes:

[for (;;)]
Post by Hermann Riemann
Post by Rainer Weikusat
Richtige Schleifen habe zB Initialisierungs-Anweisungen,
mache_nichts();
ist doch eine richtige Schleife.
Schleifen die ich schreiben muss, haben eher regelmaessig als
ausnahmsweise mehr und komplizierteren Initialisierungscode, als man
sinnvollerweise in einer for (;;)-Zeile unterbringen koennte insofern
das syntaktisch ueberhaupt moeglich ist.
Post by Hermann Riemann
Post by Rainer Weikusat
Selbst wenn man das im ersten Abschnitt von for unterbringen koennte,
sollte man das lieber lassen. Die Baby-Initiasierung und die
Moeglichkeit, dass letzte Statement der Schleife ans Ende ihrer ersten
Zeile zu ziehen ("Wisu denn blus?") machen nur die Bedingung
unkenntlich.
for (int i=0; i<end_wert; i++)
Das halte ich meist für eine bessere Ordnung als irgendwo
im Schleifenrumpf i++ zu "verstecken,
Falls 'Veraendern der Schleifenvariablen' tatsaechlich der letzte
Verarbeitungsschritt einer Schleife ist, kann man das am Ende tun. Das
ist ebenfalls eine feste Position.
Post by Hermann Riemann
oder bei einer langen Schleife außerhalb des Sichtbereiches
( Papier andere Seite; Bildschirm >=1 Bild blättern. )
"No reason to put lipstick on a pig". Falls eine Schleife nicht auf eine
Bildschirmseite passt, ist sie entschieden *zu* lang.
Helmut Schellong
2017-03-10 22:34:53 UTC
Permalink
Post by Rainer Weikusat
Schleifen die ich schreiben muss, haben eher regelmaessig als
ausnahmsweise mehr und komplizierteren Initialisierungscode, als man
sinnvollerweise in einer for (;;)-Zeile unterbringen koennte insofern
das syntaktisch ueberhaupt moeglich ist.
Bei meinen Programmierbemühungen gilt das eher für Funktionen,
nicht aber für Schleifen.
Beispielsweise: static char initialized; /*...*/


Ich liebe aber auch:
--------------------
while ( PSnu=0, c=List(&lpc), ityp&ITYP_I?++KDOnu:0,
!O['t'] &&
(c<EoF
||(ityp&ITYP_I)&&(c>ADD+8&&(!(G.ityp&ITYP_P)||c!=rETURN)
||c==EoF&&(O['I']|O['P'])
&&(write(2,"Benutze exit" NL,13+NLSZ),
--KDOnu, 1))
) );
--
Mit freundlichen Grüßen
Helmut Schellong ***@schellong.biz
www.schellong.de www.schellong.com www.schellong.biz
http://www.schellong.de/c.htm
Volker Borchert
2017-03-11 02:07:51 UTC
Permalink
Post by Rainer Weikusat
Falls eine Schleife nicht auf eine
Bildschirmseite passt, ist sie entschieden *zu* lang.
Eher ist der Bildschirm zu klein und/oder die Schrift zu groß.
--
"I'm a doctor, not a mechanic." Dr Leonard McCoy <***@ncc1701.starfleet.fed>
"I'm a mechanic, not a doctor." Volker Borchert <***@despammed.com>
Hermann Riemann
2017-03-11 11:58:07 UTC
Permalink
Post by Volker Borchert
Post by Rainer Weikusat
Falls eine Schleife nicht auf eine
Bildschirmseite passt, ist sie entschieden *zu* lang.
Eher ist der Bildschirm zu klein und/oder die Schrift zu groß.
In meiner shell habe ich 153 Zeilen.

Hermann
der vermutet, dass auch ein 42" 4k_Monitor im Senkrechtbetrieb
mit 9 Pixel Buchstabenhöhe nicht reichen würde.
--
http://www.hermann-riemann.de
Peter J. Holzer
2017-03-11 12:12:31 UTC
Permalink
Post by Hermann Riemann
Post by Volker Borchert
Falls eine Schleife nicht auf eine Bildschirmseite passt, ist sie
entschieden *zu* lang.
Eher ist der Bildschirm zu klein und/oder die Schrift zu groß.
In meiner shell habe ich 153 Zeilen.
Hermann
der vermutet, dass auch ein 42" 4k_Monitor im Senkrechtbetrieb
mit 9 Pixel Buchstabenhöhe nicht reichen würde.
Ah, Konjunktiv. Ich wollte gerade fragen, was Du da für einen Monitor
hast.

Hier:

hrunkner:~ 13:04 :-) 1050% stty -a
speed 38400 baud; rows 86; columns 80; line = 0;
[...]

Ich habe mal versucht, den 24"-Monitor senkrecht zu stellen, aber der
war mir zu hoch - das ist unbequem. Ich schätze, irgendwo zwischen 100
und 120 Zeichen ist bei mir die praktische Grenze, wo entweder der
Monitor zu hoch oder die Schrift zu klein zum Arbeiten wird.

Als Coding-Richtlinie würde ich "Eine einzelne Funktion muss in 66
Zeilen zu 132 Zeichen passen" postulieren.

hp
--
_ | Peter J. Holzer | Fluch der elektronischen Textverarbeitung:
|_|_) | | Man feilt solange an seinen Text um, bis
| | | ***@hjp.at | die Satzbestandteile des Satzes nicht mehr
__/ | http://www.hjp.at/ | zusammenpaßt. -- Ralph Babel
Volker Borchert
2017-03-11 18:26:58 UTC
Permalink
Post by Peter J. Holzer
Als Coding-Richtlinie würde ich "Eine einzelne Funktion muss in 66
Zeilen zu 132 Zeichen passen" postulieren.
Dann gibt es eine große Zahl Brocken und Bröckchen, entweder
mit unerfreulich langen Argmentlisten oder Speicherflattern
durch kurzlebige struct.
--
"I'm a doctor, not a mechanic." Dr Leonard McCoy <***@ncc1701.starfleet.fed>
"I'm a mechanic, not a doctor." Volker Borchert <***@despammed.com>
Rainer Weikusat
2017-03-11 21:13:36 UTC
Permalink
Post by Volker Borchert
Post by Peter J. Holzer
Als Coding-Richtlinie würde ich "Eine einzelne Funktion muss in 66
Zeilen zu 132 Zeichen passen" postulieren.
Dann gibt es eine große Zahl Brocken und Bröckchen, entweder
mit unerfreulich langen Argmentlisten oder Speicherflattern
durch kurzlebige struct.
Weder das eine noch das andere ist der Fall. 66 - 132 Zeilen ist auch
schon viel zu lang. Es ist vollkommen moeglich, Programme anders als
"Riesenhaufen unstrukturierten, sequentiellen Codes, der einen grossen
Satz 'gemeinsamer' dh 'globaler' Variablen fuer Datenkommunikation
benutzt" zu schreiben. Dazu muss man lediglich mal ueber die "Mit diesem
Teeloeffel muss ich bis uebermorgen einen Alpentunnel gegraben haben, da
heisst es schaufeln, was das Zeug haelt!"-Mentalitaet hinwegkommen.

Man muss das nicht gleich auf 'Linux-Qualitaeten' aufblasen, wo
man erst auf Auruftiefe sechs bis sieben, verteilt auf ebensoviele
unterschiedliche Dateien, mal an Code kommt, der etwas anderes tut, als
das ehemals fuer geeignet angesehene Interface zu benutzen.

Praktisches Beispiel: Der racoon-Code, der eine IPsec Phase 1 SA Payload
zusammenbaut. Im Original waren das 3 Funktionen mit einer Gesamtlaenge
von 271 und einer durchschnittlichen Laenge von 90.3... Zeilen. Dieser
Code wurde pro 'Phase 1'-Verhandlung 2x aufgerufen, einmal um die
(konstante!) Laenge des erforderliche Puffers zu berechnen, und einmal,
um den nun allozierten Puffer mit Daten zu fuellen. Fuer den ersten
Durchlauf wurde der 'Datenfuellcode' in Abhaengigkeit von einem
Parameter uebersprungen, im zweiten Durchlauf wurde die Laenge ein
weiteres Mal nutzloserweise mitberechnet.

Neuere iOS-Geraete senden eine recht groesse Menge von Algorithmen- und
DH-Gruppenkombinationen in einem Phase 1 Proposal/ Vorschlag. Die
VPN-Server, mit denen ich zu tun habe (NB: Das ist ein kommerzielles
Produkt, keine [semi-]private Bastelei) sollten dieselbe Menge von
Kombinationen anbieten koennen. Mit der 'standard'-racoon
Konfigurations-Syntax haette man dazue ein 3/4-Schreibmachinenseite
(geschaetzt) mit groesstenteils identischem Text fuellen muessen. Ich
bin generell gegen "copy'n'paste"-Wahnsinn (siehe 'Alpentunnel'),
deswegen habe ich ein zusaetzliches Syntax-Element hinzugefuegt, mit
dessen Hilfe man eine Liste von 'Verschluesselung/ Hash/
DH-Gruppe'-Kombinationen als Bestandteil einer proposal-Definition
angeben kann und die dahinterliegenden Datenstrukturen entsprechend
geaendert. Das zog einer entsprechende Ueberarbeitung des oben
beschriebenen Code nach sich.

Das Resultat hat acht Funktionen mit einer Gesamtlaenge von 135 Zeilen
und einer durchschnittlichen Laenge von 16.9 Zeilen, berechnet weniger
sinnloses Zeug, und hat ausserdem noch mehr features.
Hermann Riemann
2017-03-11 19:26:09 UTC
Permalink
Post by Peter J. Holzer
Als Coding-Richtlinie würde ich "Eine einzelne Funktion muss in 66
Zeilen zu 132 Zeichen passen" postulieren.
132 Zeichen pro Zeile?

enum was ={ eins , zwei , drei };
char *was_txt[] ={"eins","zwei","drei"};

Damit sowas auch auch bei enum mit vielen Werten geht,
sollte die Zeile schon genügend lang sein.
( Sowas ist nützlich für Testausgabe zum Fehler finden.)

Auch tabellennartige Zuweisungen, oder *printf-Anweisungen
können länglich werden.

Hermann
der sich noch an Monitore mit 64 Spalten erinnert,
aber heutzutage 300 pro Monitor könnte.
--
http://www.hermann-riemann.de
Peter J. Holzer
2017-03-12 00:54:47 UTC
Permalink
Post by Hermann Riemann
Post by Peter J. Holzer
Als Coding-Richtlinie würde ich "Eine einzelne Funktion muss in 66
Zeilen zu 132 Zeichen passen" postulieren.
132 Zeichen pro Zeile?
Ja. 80 finde ich übertrieben konservativ ;-).
Post by Hermann Riemann
enum was ={ eins , zwei , drei };
char *was_txt[] ={"eins","zwei","drei"};
Damit sowas auch auch bei enum mit vielen Werten geht,
sollte die Zeile schon genügend lang sein.
Bei einem enum mit vielen Werten sollte man Zeilenumbrüche einbauen.

Wenn Du Dir Sorgen um die Synchronisation machst, kannst Du das in C
auch so schreiben:

enum was {
eins,
zwei,
drei
};
char *was_txt[] = {
[eins] = "eins",
[zwei] = "zwei",
[drei] = "drei",
};

Da ist zwar ein bisschen Duplikation drin, aber was_txt lässt sich
einfach per Textersatz aus was generieren (vernünftigen Editor
vorausgesetzt), und es funktioniert auch weiterhin, wenn Du die Werte
des enums mal ändern musst, oder einfach nur umsortieren möchstest:

enum was {
drei = 13,
eins = 8,
zwei = 5,
};
char *was_txt[] = {
[eins] = "eins",
[zwei] = "zwei",
[drei] = "drei",
};


Als abschreckendes Beispiel nach Deinem Muster habe ich hier
Python-Code, bei dem das Syntax-Highlighting vom vim nicht mehr
funktioniert, weil manche Zeilen über 3000 Zeichen lang sind.

(Ich gebe zu, dass ich manchmal die 132 Zeichen auch überschreite, weil
ich z.B. eine Initialisierung einer zweidimensionalen Struktur (z.B.
array of struct[1]) in 150 Zeichen noch hübsch tabellarisch hinbekomme,
und das für mich den Nachteil der längeren Zeilen überwiegt. Aber da
überlege ich schon zweimal, ob das wirklich sein muss.)

hp

[1] Eher array of dict bzw. array of hash in den von mir bevorzugten
Sprachen. Aber wir sind hier in dclc.
--
_ | Peter J. Holzer | Fluch der elektronischen Textverarbeitung:
|_|_) | | Man feilt solange an seinen Text um, bis
| | | ***@hjp.at | die Satzbestandteile des Satzes nicht mehr
__/ | http://www.hjp.at/ | zusammenpaßt. -- Ralph Babel
Hermann Riemann
2017-03-12 05:05:16 UTC
Permalink
Post by Peter J. Holzer
Post by Hermann Riemann
Post by Peter J. Holzer
Als Coding-Richtlinie würde ich "Eine einzelne Funktion muss in 66
Zeilen zu 132 Zeichen passen" postulieren.
132 Zeichen pro Zeile?
Ja. 80 finde ich übertrieben konservativ ;-).
Post by Hermann Riemann
enum was ={ eins , zwei , drei };
char *was_txt[] ={"eins","zwei","drei"};
Damit sowas auch auch bei enum mit vielen Werten geht,
sollte die Zeile schon genügend lang sein.
Bei einem enum mit vielen Werten sollte man Zeilenumbrüche einbauen.
Wenn Du Dir Sorgen um die Synchronisation machst, kannst Du das in C
enum was {
eins,
zwei,
drei
};
char *was_txt[] = {
[eins] = "eins",
[zwei] = "zwei",
[drei] = "drei",
};
Da ist zwar ein bisschen Duplikation drin, aber was_txt lässt sich
einfach per Textersatz aus was generieren (vernünftigen Editor
vorausgesetzt), und es funktioniert auch weiterhin, wenn Du die Werte
enum was {
drei = 13,
eins = 8,
zwei = 5,
};
char *was_txt[] = {
[eins] = "eins",
[zwei] = "zwei",
[drei] = "drei",
};
Also ein Python3 Programm schreiben, welches so was erledigt.

enum was ={ eins , zwei , drei };

statt
Post by Peter J. Holzer
enum was {
drei = 13,
eins = 8,
zwei = 5,
};
erspart blättern auf dem Bildschirm
was weniger suchen beutet
und weniger Ablenkung durch umblättern.
Post by Peter J. Holzer
Als abschreckendes Beispiel nach Deinem Muster habe ich hier
Python-Code, bei dem das Syntax-Highlighting vom vim nicht mehr
funktioniert, weil manche Zeilen über 3000 Zeichen lang sind.
Es gibt gvim, emacs, xemacs kate vi.
Je nach Situation verwende ich unterschiedliche Editoren.
Post by Peter J. Holzer
[1] Eher array of dict bzw. array of hash in den von mir bevorzugten
Sprachen. Aber wir sind hier in dclc.
Vor 10 Jahre habe ich fast nur xemacs und ANSI C verwendet.
Mit den Bücher Programmieren in C von Kernighan/Ritchie
und der Linux Unix Kurzreferenz (für malloc etc).

Die meisten Programme erledige ich heutzutage mit Python3.
Einfach weil sie wenig Daten && wenig Berechnung haben.
Sind diese Bedinungen nicht erfüllt:
viele Daten || z.B. Grafik, nehme ich C(99).

Hermann
der die Syntax in C von [eins] bisher nicht kannte.
--
http://www.hermann-riemann.de
Peter J. Holzer
2017-03-12 10:08:30 UTC
Permalink
Post by Hermann Riemann
Post by Peter J. Holzer
Post by Hermann Riemann
Post by Peter J. Holzer
Als Coding-Richtlinie würde ich "Eine einzelne Funktion muss in 66
Zeilen zu 132 Zeichen passen" postulieren.
132 Zeichen pro Zeile?
Ja. 80 finde ich übertrieben konservativ ;-).
Post by Hermann Riemann
enum was ={ eins , zwei , drei };
char *was_txt[] ={"eins","zwei","drei"};
Damit sowas auch auch bei enum mit vielen Werten geht,
sollte die Zeile schon genügend lang sein.
Bei einem enum mit vielen Werten sollte man Zeilenumbrüche einbauen.
Wenn Du Dir Sorgen um die Synchronisation machst, kannst Du das in C
enum was {
eins,
zwei,
drei
};
char *was_txt[] = {
[eins] = "eins",
[zwei] = "zwei",
[drei] = "drei",
};
Da ist zwar ein bisschen Duplikation drin, aber was_txt lässt sich
einfach per Textersatz aus was generieren (vernünftigen Editor
vorausgesetzt),
[...]
Post by Hermann Riemann
Also ein Python3 Programm schreiben, welches so was erledigt.
Nein, ich dachte eher daran, im vim

:'<,'>s/ *\([^ ]*\).*/[\1] = "\1",/

zu tippen. Dafür braucht man kein Python, das kann der Editor.
Post by Hermann Riemann
enum was ={ eins , zwei , drei };
statt
Post by Peter J. Holzer
enum was {
drei = 13,
eins = 8,
zwei = 5,
};
erspart blättern auf dem Bildschirm
was weniger suchen beutet
und weniger Ablenkung durch umblättern.
Bei drei Elementen, ja. Vielleicht auch bei zehn oder zwanzig. Aber Du
warst über die Zumutung, sich auf 132 Zeichen pro Zeile beschränken zu
müssen, entsetzt, also geht es offensichtlich um längere Listen. Und da
bin ich der Meinung, dass es nicht sinnvoll ist, die in einer einzelnen
Zeile zusammenzupferchen und jenseits des rechten Bildschirmrands zu
"verstecken". Wenn es aus irgendeinem Grund lange Listen im Source-Code
geben muss, soll man die auch sehen. Statische Initialisierungen kann
man ja leicht in ein eigenes Source-File auslagern. Oder vielleicht
merkt der Programmierer, dass er das eigentlich viel leichter (und
weniger fehleranfällig) algorithmisch lösen könnte. Oder dass das gar
nicht in den Source-Code gehört, sondern in eine Datenbanktabelle.
Post by Hermann Riemann
Post by Peter J. Holzer
Als abschreckendes Beispiel nach Deinem Muster habe ich hier
Python-Code, bei dem das Syntax-Highlighting vom vim nicht mehr
funktioniert, weil manche Zeilen über 3000 Zeichen lang sind.
Es gibt gvim, emacs, xemacs kate vi.
Je nach Situation verwende ich unterschiedliche Editoren.
Gvim hat natürlich das gleiche Problem wie vim, weil es derselbe Editor
ist ;-). Aber es geht hier nicht darum, dass ein bestimmtes Tool ein
Problem hat (was man durch die Wahl eines anderen Tools umgehen könnte),
sondern dass der Programmierer irrwitzig lange Zeilen geschrieben hat.
Der Autor des Syntax-Highlighters für Python im vim (oder des
Highlighting-Frameworks im vim - ich habe nicht überprüft, ob das Limit
auch für andere Sprachen gilt) hat sicherlich geglaubt, dass er mit
seinem 3000-Zeichen-Limit weit jenseits von dem liegt, was jemals ein
zurechnungsfähiger Programmierer produzieren würde. (Und vermutlich
hatte er recht.)
Post by Hermann Riemann
Hermann
der die Syntax in C von [eins] bisher nicht kannte.
Tja, auch C entwickelt sich weiter. Das gibt es allerdings schon seit
C99, also mittlerweile seit 18 Jahren.

hp
--
_ | Peter J. Holzer | Fluch der elektronischen Textverarbeitung:
|_|_) | | Man feilt solange an seinen Text um, bis
| | | ***@hjp.at | die Satzbestandteile des Satzes nicht mehr
__/ | http://www.hjp.at/ | zusammenpaßt. -- Ralph Babel
Hermann Riemann
2017-03-12 11:34:21 UTC
Permalink
Post by Peter J. Holzer
Post by Hermann Riemann
Post by Peter J. Holzer
enum was {
eins,
zwei,
drei
};
char *was_txt[] = {
[eins] = "eins",
[zwei] = "zwei",
[drei] = "drei",
};
Da ist zwar ein bisschen Duplikation drin, aber was_txt lässt sich
einfach per Textersatz aus was generieren (vernünftigen Editor
vorausgesetzt),
[...]
Post by Hermann Riemann
Also ein Python3 Programm schreiben, welches so was erledigt.
Nein, ich dachte eher daran, im vim
:'<,'>s/ *\([^ ]*\).*/[\1] = "\1",/
zu tippen. Dafür braucht man kein Python, das kann der Editor.
"der" Editor? Jeder von mir verwendete Editor?
Und wenn ich
enum was={ eins, zwei, /* später zweieinhalb, */
drei};
schreibe?

( Obiges regexpr müsste ich erst anhand eines Buches entschlüsseln.)
Post by Peter J. Holzer
Bei drei Elementen, ja. Vielleicht auch bei zehn oder zwanzig. Aber Du
warst über die Zumutung, sich auf 132 Zeichen pro Zeile beschränken zu
müssen, entsetzt,
Entsetzt nicht. Ich musste jahrelang Lochkartenlänge
max. 80 Zeichen mit weiteren Einschränkungen erleben.
Post by Peter J. Holzer
also geht es offensichtlich um längere Listen. Und da
bin ich der Meinung, dass es nicht sinnvoll ist, die in einer einzelnen
Zeile zusammenzupferchen und jenseits des rechten Bildschirmrands zu
"verstecken".
Bei meinen 3 Bildschirmen habe ich bis über 900 Spalten.
http://www.hermann-riemann.de/pic/Arbeitsplatz.jpg
Allerdings machen bei langen Zeilen beim Lesen der Zeilenwechsel Probleme.
Das mit der (genauen) Zahl sehe ich nicht so streng.
Meist ist schlicht beste Lesbarkeit entscheidend.
Post by Peter J. Holzer
Post by Hermann Riemann
Post by Peter J. Holzer
Als abschreckendes Beispiel nach Deinem Muster habe ich hier
Python-Code, bei dem das Syntax-Highlighting vom vim nicht mehr
funktioniert, weil manche Zeilen über 3000 Zeichen lang sind.
Erinnert mich an jemand der options für kommentarzeilen für Fortran
programmierte.
A-Z sind sind 26 Buchstaben.
Als ich dann 27 mal den gleichen Buchstaben als Option angab ..

Übrigens von computer aus pseudocode generierte Programme
müssen sich nicht an die 3000 Spalten halten,
weil C \n im source wie ein blank behandelt.
Wenn dann ein Mensch in so einem Programm dann Fehler suchen muß.
( Die von einem computer generierte Programme,
in denen ich Fehler suchen musste, waren allerdings gut lesbar.)
Post by Peter J. Holzer
Post by Hermann Riemann
Es gibt gvim, emacs, xemacs kate vi.
Je nach Situation verwende ich unterschiedliche Editoren.
Gvim hat natürlich das gleiche Problem wie vim, weil es derselbe Editor
ist ;-). Aber es geht hier nicht darum, dass ein bestimmtes Tool ein
Problem hat (was man durch die Wahl eines anderen Tools umgehen könnte),
sondern dass der Programmierer irrwitzig lange Zeilen geschrieben hat.
Der Autor des Syntax-Highlighters für Python im vim (oder des
Highlighting-Frameworks im vim - ich habe nicht überprüft, ob das Limit
auch für andere Sprachen gilt) hat sicherlich geglaubt, dass er mit
seinem 3000-Zeichen-Limit weit jenseits von dem liegt, was jemals ein
zurechnungsfähiger Programmierer produzieren würde. (Und vermutlich
hatte er recht.)
Für fgets auf eigenen Programme nehme ich manchmal ein Puffer
von 4096.
Bei unbekannten Programme schaue ich erst mit lstat nach,
wie lange das Programm ist, dann etwas wie p00=malloc(st_size+16);
die Längen vorne und hinten mit memset(ptr,'\0,8) belegt um mit
pointergrenzen wie *p-1 *p+1 besser umgehen zu könnnen + aligment.
und dann read(mit p00+8 und st_size) den ganzen Dateiinhalt in einem Puffer.

Gvim verwende ich selten,
weil nach dem reboot erstmal kein Inhalt angezeigt wird.
kate ist da gut, wenn das Fenster nicht unterteilt wird.
Mäßiges syntax highlighting.

Hermann
der C Programme etwas Python ähnlich macht,
in dem er { } und }; und deren Wiederholungen an Zeilenende schreibt,
was seine Lesbarkeit spürbar erhöht.
--
http://www.hermann-riemann.de
Peter J. Holzer
2017-03-12 12:39:23 UTC
Permalink
Post by Hermann Riemann
Post by Peter J. Holzer
Post by Hermann Riemann
Post by Peter J. Holzer
enum was {
eins,
zwei,
drei
};
char *was_txt[] = {
[eins] = "eins",
[zwei] = "zwei",
[drei] = "drei",
};
Da ist zwar ein bisschen Duplikation drin, aber was_txt lässt sich
einfach per Textersatz aus was generieren (vernünftigen Editor
vorausgesetzt),
[...]
Post by Hermann Riemann
Also ein Python3 Programm schreiben, welches so was erledigt.
Nein, ich dachte eher daran, im vim
:'<,'>s/ *\([^ ]*\).*/[\1] = "\1",/
zu tippen. Dafür braucht man kein Python, das kann der Editor.
"der" Editor? Jeder von mir verwendete Editor?
Es reicht, wenn es einer kann (Du hast ja selbst geschrieben, dass Du
verschiedene Editoren für verschiedene Zwecke verwendest). Unter den von
Dir erwähnten Editoren können es zumindest die vi-Abkömmlinge und Emacs.

(Und ja, ich bin der Meinung, dass man als Programmierer mindestens
einen Editor im Portfolio haben sollte, der regexp-basierte Ersetzung
beherrscht. Und dass man das auch anwenden kann.)
Post by Hermann Riemann
Und wenn ich
enum was={ eins, zwei, /* später zweieinhalb, */
drei};
schreibe?
Sinnvollerweise schreibt man natürlich Ausdrücke, von denen man vorhat,
sie mittels Suchen und Ersetzen umzuwandeln, so, dass das leicht geht.
Wenn Du das als:

enum was={
eins,
zwei, /* später zweieinhalb, */
drei
};

schreibst, funktioniert mein Ausdruck von oben.

Und auch als Mensch finde ich das deutlich lesbarer als mit dem
unmotivierten Zeilenumbruch in der Mitte.

hp
--
_ | Peter J. Holzer | Fluch der elektronischen Textverarbeitung:
|_|_) | | Man feilt solange an seinen Text um, bis
| | | ***@hjp.at | die Satzbestandteile des Satzes nicht mehr
__/ | http://www.hjp.at/ | zusammenpaßt. -- Ralph Babel
Hermann Riemann
2017-03-12 14:24:29 UTC
Permalink
Post by Peter J. Holzer
Post by Hermann Riemann
Post by Peter J. Holzer
Post by Hermann Riemann
Post by Peter J. Holzer
enum was {
eins,
zwei,
drei
};
char *was_txt[] = {
[eins] = "eins",
[zwei] = "zwei",
[drei] = "drei",
};
Da ist zwar ein bisschen Duplikation drin, aber was_txt lässt sich
einfach per Textersatz aus was generieren (vernünftigen Editor
vorausgesetzt),
[...]
Post by Hermann Riemann
Also ein Python3 Programm schreiben, welches so was erledigt.
Nein, ich dachte eher daran, im vim
:'<,'>s/ *\([^ ]*\).*/[\1] = "\1",/
zu tippen. Dafür braucht man kein Python, das kann der Editor.
"der" Editor? Jeder von mir verwendete Editor?
Es reicht, wenn es einer kann (Du hast ja selbst geschrieben, dass Du
verschiedene Editoren für verschiedene Zwecke verwendest). Unter den von
Dir erwähnten Editoren können es zumindest die vi-Abkömmlinge und Emacs.
Nur deswegen die Arbeit machen, wegen einer source vorübergehend
den Editor zu wechseln?
Und wenn das eine Programmierumgebung wie qt oder Arduino nicht vorsieht?
Post by Peter J. Holzer
(Und ja, ich bin der Meinung, dass man als Programmierer mindestens
einen Editor im Portfolio haben sollte, der regexp-basierte Ersetzung
beherrscht. Und dass man das auch anwenden kann.)
Bisher habe ich von regexp nur sehr wenig benötigt. ( ? und * )
Post by Peter J. Holzer
Post by Hermann Riemann
Und wenn ich
enum was={ eins, zwei, /* später zweieinhalb, */
drei};
schreibe?
Sinnvollerweise schreibt man natürlich Ausdrücke, von denen man vorhat,
sie mittels Suchen und Ersetzen umzuwandeln, so, dass das leicht geht.
Da bastele ich eher mir mit Python3
(früher hätte ich das mit C gemacht)
einmal ein Umsetzprogramm
und schreibe die enums so, wie ich sie
für nützlich halte.
Post by Peter J. Holzer
enum was={
eins,
zwei, /* später zweieinhalb, */
drei
};
schreibst, funktioniert mein Ausdruck von oben.
Das sind 5 statt 2 Zeilen und bei noch mehr Werten
wird es noch schlimmer, die mich durch erzwungenes scrollen
beim Gedankengang stören.
Post by Peter J. Holzer
Und auch als Mensch finde ich das deutlich lesbarer als mit dem
unmotivierten Zeilenumbruch in der Mitte.
Dieser Zeilenumbruch war durch die Beschränkung
der Zeilenlänge beim newsreader bzw.
als Beispiel gegeben.
Normalerweise schreibe ich enum bis fast zum Fensterrand
ohne Wortumbruch. ( wie bei html)

Hermann
der wohl bald wieder einen neuen
unprettyPrinter basteln wird.
--
http://www.hermann-riemann.de
Helmut Schellong
2017-03-13 13:09:04 UTC
Permalink
Post by Hermann Riemann
Bisher habe ich von regexp nur sehr wenig benötigt. ( ? und * )
? und * sind Suchmuster für Dateinamenbildung und haben mit
'Regulären Ausdrücken' nur wenig gemeinsam.

'Richtige' Reguläre Ausdrücke sind eine große Macht!
Es gibt da BRE, ERE und XRE.

http://www.schellong.de/htm/bshmnk.htm#xregexpR

http://www.schellong.de/htm/exprcatv.htm

Vorstehend meine BRA, die ich in Shell-Skripts geschrieben habe.
Im Editor vim/gvim habe ich noch viel mehr RA geschrieben;
sicher nnnnn Stück.
--
Mit freundlichen Grüßen
Helmut Schellong ***@schellong.biz
www.schellong.de www.schellong.com www.schellong.biz
http://www.schellong.de/c.htm
G.B.
2017-03-12 07:52:43 UTC
Permalink
Post by Peter J. Holzer
enum was {
drei = 13,
eins = 8,
zwei = 5,
};
char *was_txt[] = {
[eins] = "eins",
[zwei] = "zwei",
[drei] = "drei",
};
Verstehe ich richtig, dass die Länge von *was_txt sich
nach den vereinbarten Werten der enums richtet?
Peter J. Holzer
2017-03-12 10:13:08 UTC
Permalink
Post by G.B.
Post by Peter J. Holzer
enum was {
drei = 13,
eins = 8,
zwei = 5,
};
char *was_txt[] = {
[eins] = "eins",
[zwei] = "zwei",
[drei] = "drei",
};
Verstehe ich richtig, dass die Länge von *was_txt sich
nach den vereinbarten Werten der enums richtet?
Nicht von *was_txt, sondern von was_txt.

hp
--
_ | Peter J. Holzer | Fluch der elektronischen Textverarbeitung:
|_|_) | | Man feilt solange an seinen Text um, bis
| | | ***@hjp.at | die Satzbestandteile des Satzes nicht mehr
__/ | http://www.hjp.at/ | zusammenpaßt. -- Ralph Babel
G.B.
2017-03-13 06:45:15 UTC
Permalink
Post by Peter J. Holzer
Post by G.B.
Post by Peter J. Holzer
enum was {
drei = 13,
eins = 8,
zwei = 5,
};
char *was_txt[] = {
[eins] = "eins",
[zwei] = "zwei",
[drei] = "drei",
};
Verstehe ich richtig, dass die Länge von *was_txt sich
nach den vereinbarten Werten der enums richtet?
Nicht von *was_txt, sondern von was_txt.
Stimmt.
G.B.
2017-03-12 07:54:29 UTC
Permalink
Post by Peter J. Holzer
Post by Hermann Riemann
Post by Peter J. Holzer
Als Coding-Richtlinie würde ich "Eine einzelne Funktion muss in 66
Zeilen zu 132 Zeichen passen" postulieren.
132 Zeichen pro Zeile?
Ja. 80 finde ich übertrieben konservativ ;-).
Wer gelegentlich an konservativen Textbildschirmen
an alten server-Systemen vor Ort arbeiten muss,
kommt meistens nicht umhin, sich die Funktion in Gänze
im Kopf vorzustellen...
Rainer Weikusat
2017-03-12 10:54:53 UTC
Permalink
Post by Peter J. Holzer
Post by Hermann Riemann
Post by Peter J. Holzer
Als Coding-Richtlinie würde ich "Eine einzelne Funktion muss in 66
Zeilen zu 132 Zeichen passen" postulieren.
132 Zeichen pro Zeile?
Ja. 80 finde ich übertrieben konservativ ;-).
Post by Hermann Riemann
enum was ={ eins , zwei , drei };
char *was_txt[] ={"eins","zwei","drei"};
Damit sowas auch auch bei enum mit vielen Werten geht,
sollte die Zeile schon genügend lang sein.
Bei einem enum mit vielen Werten sollte man Zeilenumbrüche einbauen.
Wenn Du Dir Sorgen um die Synchronisation machst, kannst Du das in C
enum was {
eins,
zwei,
drei
};
char *was_txt[] = {
[eins] = "eins",
[zwei] = "zwei",
[drei] = "drei",
};
Da ist zwar ein bisschen Duplikation drin, aber was_txt lässt sich
einfach per Textersatz aus was generieren
Das kann man sich mit Hilfe des Praeprozessors auch etwas einfacher
machen:

-------
#include <stdio.h>
#include <stdlib.h>

enum {
jonathan,
moewe,
boot,
wurstfabrik,
schornholm,
beutelratte
};

char *names[] = {
#define n_(s) [s] = #s

n_(jonathan),
n_(moewe),
n_(boot),
n_(wurstfabrik),
n_(schornholm),
n_(beutelratte)

#undef n_
};

int main(int argc, char **argv)
{
int which;

if (argc < 2) {
fputs("Bitte?\n", stderr);
return 1;
}

which = atoi(argv[1]);
if (which > beutelratte) {
fputs("Hamma nich!\n", stderr);
return 1;
}

puts(names[which]);

return 0;
}
Rainer Weikusat
2017-03-12 10:57:35 UTC
Permalink
Rainer Weikusat <***@talktalk.net> writes:

[...]
Post by Rainer Weikusat
int main(int argc, char **argv)
{
int which;
Wie eigentlich fast immer waere unsigned hier eine bessere Wahl gewesen
...
Hermann Riemann
2017-03-12 11:38:00 UTC
Permalink
Post by Rainer Weikusat
Post by Rainer Weikusat
int main(int argc, char **argv)
{
int which;
Wie eigentlich fast immer waere unsigned hier eine bessere Wahl gewesen
bei argc oder argv?

Hermann
der meint, unsigned char sei bei utf8 Zeichen besser.
--
http://www.hermann-riemann.de
Peter J. Holzer
2017-03-12 12:52:53 UTC
Permalink
Post by Hermann Riemann
Post by Rainer Weikusat
Post by Rainer Weikusat
int main(int argc, char **argv)
{
int which;
Wie eigentlich fast immer waere unsigned hier eine bessere Wahl gewesen
bei argc oder argv?
Bei which.

(bei argc wäre size_t sinnvoll, aber das liegt nicht im
Ermessensspielraum des Programmierers.)
Post by Hermann Riemann
Hermann
der meint, unsigned char sei bei utf8 Zeichen besser.
Auch bei iso-8859-1. Eigentlich bei jedem Character Set außer ISO-646.
Dass char signed oder unsigned sein kann und auf den meisten
Implemenationen signed ist, halte ich für einen historischen Unfall.
Dass man die Funktionen aus <ctype.h> nicht ohne Cast auf char-Werte
anwenden kann, ist ein Unding.
Allerdings hätte man den wohl schon vor 30 Jahren fixen müssen.

Wenn man ein Programm schreibt, das nennenswert Textverarbeitung
betreibt, ist es wahrscheinlich sinnvoll[1], sich einen eigenen
Stringtyp auf Basis von uint8_t zu definieren (wenn man nicht gleich auf
wchar_t geht). Für die Standard-Stringfunktionen muss man dann casten,
aber die sind ohnehin nur begrenzt nützlich.

hp

[1] ... eine andere Programmiersprache als C zu verwenden, sollte ich
hier eigentlich schreiben.
--
_ | Peter J. Holzer | Fluch der elektronischen Textverarbeitung:
|_|_) | | Man feilt solange an seinen Text um, bis
| | | ***@hjp.at | die Satzbestandteile des Satzes nicht mehr
__/ | http://www.hjp.at/ | zusammenpaßt. -- Ralph Babel
Hermann Riemann
2017-03-12 14:42:34 UTC
Permalink
Post by Peter J. Holzer
Post by Hermann Riemann
Post by Rainer Weikusat
Post by Rainer Weikusat
int main(int argc, char **argv)
{
int which;
Wie eigentlich fast immer waere unsigned hier eine bessere Wahl gewesen
bei argc oder argv?
Bei which.
(bei argc wäre size_t sinnvoll, aber das liegt nicht im
Ermessensspielraum des Programmierers.)
Da hätte ich Bedenken wegen des Parameterübergabetyps
weil size_t heutzutage int64_t und argc int32_t ist.
Wenn jeder Parameter in der Argumentliste heutzutage 64 bit ist,
mag das angehen.
Post by Peter J. Holzer
Post by Hermann Riemann
Hermann
der meint, unsigned char sei bei utf8 Zeichen besser.
Wenn man ein Programm schreibt, das nennenswert Textverarbeitung
betreibt, ist es wahrscheinlich sinnvoll[1], sich einen eigenen
Stringtyp auf Basis von uint8_t zu definieren (wenn man nicht gleich auf
wchar_t geht).
Früher, als ich in C noch (privat) viel Textverarbeitung programmierte,
musste ich immer des öfteren aufpassen, unsigned char zu nehmen.

wchar_t ist riskant da utf-zeichen Werte auch größer als 65635 sein
können. Hinzu kommt das Problem mit den diakritischen Zeichen
wo ein Buchstabe aus mehreren Zahlen bestehen kann.

Hermann
der bei seiner Ausbildung Buchstaben mit 6 Bit hatte
( Reste dieses Zeichensatzes sind noch in C vorhanden.)
und beruflich meist EBCDIC Zeichensatz.
--
http://www.hermann-riemann.de
Peter J. Holzer
2017-03-12 16:56:37 UTC
Permalink
Post by Hermann Riemann
Post by Peter J. Holzer
Post by Hermann Riemann
Post by Rainer Weikusat
Post by Rainer Weikusat
int main(int argc, char **argv)
{
int which;
Wie eigentlich fast immer waere unsigned hier eine bessere Wahl gewesen
bei argc oder argv?
Bei which.
(bei argc wäre size_t sinnvoll, aber das liegt nicht im
Ermessensspielraum des Programmierers.)
Da hätte ich Bedenken wegen des Parameterübergabetyps
weil size_t heutzutage int64_t und argc int32_t ist.
Wie bereits geschrieben: Das liegt NICHT im Ermessen des Programmierers.
Der Standard definiert, dass der erste Parameter der Funktion main den
Typ int hat, also muss der Programmierer int hinschreiben.

Ich meinte, dass das eine Inkonsistenz im Standard ist. Generell wird
dort überall, wo ein Parameter eine Anzahl von Elementen enthält, der
Typ size_t verwendet. argc würde in dieses Muster passen, hat aber Typ
int, nicht size_t. Es wäre konsequent gewesen, wenn damals für diesen
Parameter der Typ size_t festgelegt worden wäre. Hat man aber nicht
gemacht. Warum? Hat man drauf vergessen, oder hatte man schwerwiegende
Gründe? Ich vermute letzteres, aber ich finde die Rationale zu C89
gerade nicht (wo kann ich die denn hingegeben haben?).
Post by Hermann Riemann
Post by Peter J. Holzer
Post by Hermann Riemann
Hermann
der meint, unsigned char sei bei utf8 Zeichen besser.
Wenn man ein Programm schreibt, das nennenswert Textverarbeitung
betreibt, ist es wahrscheinlich sinnvoll[1], sich einen eigenen
Stringtyp auf Basis von uint8_t zu definieren (wenn man nicht gleich auf
wchar_t geht).
Früher, als ich in C noch (privat) viel Textverarbeitung programmierte,
musste ich immer des öfteren aufpassen, unsigned char zu nehmen.
wchar_t ist riskant da utf-zeichen
Unicode-Zeichen, nicht UTF-Zeichen.
Post by Hermann Riemann
Werte auch größer als 65635 sein können.
Ein 16-Bit wchar_t würde ich als Bug bezeichnen. wchar_t muss "distinct
codes for all members of the largest extended character set"
repräsentieren können, und in Unicode gibt es mehr als 65535
verschiedene Zeichen (derzeit etwas über 128000).

Natürlich muss ein System nicht Unicode unterstützen, um konform zu
sein, aber auf jedem System, auf dem man Texte verarbeiten möchte, will
man das.

Natürlich ist ein 32-Bit-wchar_t auch keine Garantie dafür, dass die
darin gespeicherten Werte tatsächlich Unicode-Codepoints sind. Wenn man
sich nicht auf Systeme mit __STDC_ISO_10646__ beschränken will, heißt
das wohl, dass man was verwenden sollte, das nicht mit Standard
kollidiert.
Post by Hermann Riemann
Hinzu kommt das Problem mit den diakritischen Zeichen
wo ein Buchstabe aus mehreren Zahlen bestehen kann.
Das ist unabhängig vom Datentyp. Mit Combining Characters, kanonischen
Formen, Grapheme Clustern, etc. muss ein Programm, das mehr als triviale
Texttransformationen vornimmt, umgehen können. Das ist alles nicht
trivial, und man möchte da das Rad eher nicht neu erfinden.

hp
--
_ | Peter J. Holzer | Fluch der elektronischen Textverarbeitung:
|_|_) | | Man feilt solange an seinen Text um, bis
| | | ***@hjp.at | die Satzbestandteile des Satzes nicht mehr
__/ | http://www.hjp.at/ | zusammenpaßt. -- Ralph Babel
Claus Reibenstein
2017-03-12 17:13:53 UTC
Permalink
Post by Peter J. Holzer
Ich meinte, dass das eine Inkonsistenz im Standard ist. Generell
wird dort überall, wo ein Parameter eine Anzahl von Elementen
enthält, der Typ size_t verwendet. argc würde in dieses Muster
passen, hat aber Typ int, nicht size_t. Es wäre konsequent gewesen,
wenn damals für diesen Parameter der Typ size_t festgelegt worden
wäre. Hat man aber nicht gemacht. Warum?
Vermutlich aus historischen Gründen. size_t wurde erst mit ANSI-C
eingeführt. Davor gab es nur short, int und long, und damals war eben
int festgelegt worden.

Gruß
Claus
Peter J. Holzer
2017-03-12 17:31:30 UTC
Permalink
Post by Claus Reibenstein
Post by Peter J. Holzer
Ich meinte, dass das eine Inkonsistenz im Standard ist. Generell
wird dort überall, wo ein Parameter eine Anzahl von Elementen
enthält, der Typ size_t verwendet. argc würde in dieses Muster
passen, hat aber Typ int, nicht size_t. Es wäre konsequent gewesen,
wenn damals für diesen Parameter der Typ size_t festgelegt worden
wäre. Hat man aber nicht gemacht. Warum?
Vermutlich aus historischen Gründen. size_t wurde erst mit ANSI-C
eingeführt. Davor gab es nur short, int und long, und damals war eben
int festgelegt worden.
Das trifft aber auch auf alle Funktionen der Standard-Library zu. Dort
hat man sich nicht gescheut, int bzw. unsigned durch size_t zu ersetzen.

Ich vermute, dass der Grund war, dass Code der Art

int n = strlen(s);
memcpy(p, s, n);

nach der Änderung der Signaturen von strlen und memcpy weiterhin
funktioniert[1] (schlimmstenfalls muss man neu kompilieren), während das
bei

int main(argc, argv) {
int argc;
char **argv;
...
}

nicht notwendigerweise der Fall ist, wenn der aufrufende Code die
Signatur (size_t, char **) erwartet. Und fast jedes existierende
C-Programm für nicht standard-konform zu erklären, hätte wohl nicht dem
Anspruch genügt, eine existierende Sprache zu standardisieren.

hp

[1] Sofern der String, auf den s zeigt, kurz genug ist. Das ist aber
mehr eine Frage der Applikationslogik.
--
_ | Peter J. Holzer | Fluch der elektronischen Textverarbeitung:
|_|_) | | Man feilt solange an seinen Text um, bis
| | | ***@hjp.at | die Satzbestandteile des Satzes nicht mehr
__/ | http://www.hjp.at/ | zusammenpaßt. -- Ralph Babel
Claus Reibenstein
2017-03-12 20:08:52 UTC
Permalink
Post by Peter J. Holzer
Post by Claus Reibenstein
Post by Peter J. Holzer
Ich meinte, dass das eine Inkonsistenz im Standard ist. Generell
wird dort überall, wo ein Parameter eine Anzahl von Elementen
enthält, der Typ size_t verwendet. argc würde in dieses Muster
passen, hat aber Typ int, nicht size_t. Es wäre konsequent
gewesen, wenn damals für diesen Parameter der Typ size_t
festgelegt worden wäre. Hat man aber nicht gemacht. Warum?
Vermutlich aus historischen Gründen. size_t wurde erst mit ANSI-C
eingeführt. Davor gab es nur short, int und long, und damals war
eben int festgelegt worden.
Das trifft aber auch auf alle Funktionen der Standard-Library zu.
Dort hat man sich nicht gescheut, int bzw. unsigned durch size_t zu
ersetzen.
main() ist aber nun mal nicht Bestandteil der Standard-Library. Das ist
eine ganz andere Baustelle.
Post by Peter J. Holzer
Ich vermute, dass der Grund war, dass Code der Art
int n = strlen(s);
memcpy(p, s, n);
nach der Änderung der Signaturen von strlen und memcpy weiterhin
funktioniert[1] (schlimmstenfalls muss man neu kompilieren), während das
bei
int main(argc, argv) {
int argc;
char **argv;
...
}
nicht notwendigerweise der Fall ist, wenn der aufrufende Code die
Signatur (size_t, char **) erwartet. Und fast jedes existierende
C-Programm für nicht standard-konform zu erklären, hätte wohl nicht dem
Anspruch genügt, eine existierende Sprache zu standardisieren.
Womit wir bei den historischen Gründen wären.

Gruß
Claus
Peter J. Holzer
2017-03-12 23:07:35 UTC
Permalink
Post by Claus Reibenstein
Post by Peter J. Holzer
Das trifft aber auch auf alle Funktionen der Standard-Library zu.
Dort hat man sich nicht gescheut, int bzw. unsigned durch size_t zu
ersetzen.
main() ist aber nun mal nicht Bestandteil der Standard-Library.
Es ist ein Interface zwischen der Implementation und der Applikation.
Post by Claus Reibenstein
Das ist eine ganz andere Baustelle.
So anders finde ich die Baustelle nicht. Die Aufruf geht in die andere
Richtung, aber sonst ...

hp
--
_ | Peter J. Holzer | Fluch der elektronischen Textverarbeitung:
|_|_) | | Man feilt solange an seinen Text um, bis
| | | ***@hjp.at | die Satzbestandteile des Satzes nicht mehr
__/ | http://www.hjp.at/ | zusammenpaßt. -- Ralph Babel
Helmut Schellong
2017-03-12 19:32:09 UTC
Permalink
Post by Hermann Riemann
Post by Peter J. Holzer
(bei argc wäre size_t sinnvoll, aber das liegt nicht im
Ermessensspielraum des Programmierers.)
Da hätte ich Bedenken wegen des Parameterübergabetyps
weil size_t heutzutage int64_t und argc int32_t ist.
Wenn jeder Parameter in der Argumentliste heutzutage 64 bit ist,
mag das angehen.
Pointer (argv) sind ja bei LP64 64 Bit breit.
--
Mit freundlichen Grüßen
Helmut Schellong ***@schellong.biz
www.schellong.de www.schellong.com www.schellong.biz
http://www.schellong.de/c.htm
Rainer Weikusat
2017-03-12 19:48:04 UTC
Permalink
Post by Hermann Riemann
Post by Rainer Weikusat
Post by Rainer Weikusat
int main(int argc, char **argv)
{
int which;
Wie eigentlich fast immer waere unsigned hier eine bessere Wahl gewesen
bei argc oder argv?
Der Code, den ich gepostet hatte, enthielt folgende Ueberpruefung:

which = atoi(argv[1]);
if (which > beutelratte) {
fputs("Hamma nich!\n", stderr);
return 1;
}

Da which int war, kann man das Programm zum Absturz bringen (wenigstens
kann ich das) in dem man eine negative Zahl als Argument uebergibt was
dieser Test nicht erkennt. Hier haette man

if (which < jonathan || which > beutelratte) {
}

benutzen muessen oder die Variable als unsigned deklarieren. In diesem
Fall wuerde ein negatives Argument zu einer 'grossen' Zahl konvertiert,
die (wie intendiert) zur Ausfuerung des bedingten Blocks fuehrte. Weil
negative Argumente hier (wie in sehr vielen anderen Faellen) keinen Sinn
haben koennen, halte ich es fuer besser, sie von vorneherein
auszuschliessen, als die komplizierte Bedingung zu schreiben bzw zu
schreiben zu vergessen, siehe auch "Weil der Computer des Marsmaulwurfs
glaubte, bereits mehrere Kilometer tief im Inneren des Zielplaneten zu
sein, loeste der den Abwurf des Fallschirms aus." (und das bekam dem
Maulwurf nicht so gut).

int ist als Typ eigentlich nur sinnvoll, wenn mit einer Variablen
garantiert keine Berechnungen durchgefuert werden oder wenn negative
Zahlen ausdruecklich benoetigt werden.
Thomas Koenig
2017-03-12 20:54:39 UTC
Permalink
Post by Peter J. Holzer
Post by Hermann Riemann
Post by Peter J. Holzer
Als Coding-Richtlinie würde ich "Eine einzelne Funktion muss in 66
Zeilen zu 132 Zeichen passen" postulieren.
132 Zeichen pro Zeile?
Ja. 80 finde ich übertrieben konservativ ;-).
Post by Hermann Riemann
enum was ={ eins , zwei , drei };
char *was_txt[] ={"eins","zwei","drei"};
Damit sowas auch auch bei enum mit vielen Werten geht,
sollte die Zeile schon genügend lang sein.
Bei einem enum mit vielen Werten sollte man Zeilenumbrüche einbauen.
Wenn Du Dir Sorgen um die Synchronisation machst, kannst Du das in C
enum was {
eins,
zwei,
drei
};
char *was_txt[] = {
[eins] = "eins",
[zwei] = "zwei",
[drei] = "drei",
};
Ich würde bevorzugen:

#define TABLE(x) [x] = #x

char *was_txt[] = {
TABLE(eins),
TABLE(zwei),
TABLE(drei),
};
Helmut Schellong
2017-03-11 13:30:50 UTC
Permalink
Post by Hermann Riemann
Post by Volker Borchert
Post by Rainer Weikusat
Falls eine Schleife nicht auf eine
Bildschirmseite passt, ist sie entschieden *zu* lang.
Eher ist der Bildschirm zu klein und/oder die Schrift zu groß.
In meiner shell habe ich 153 Zeilen.
Was soll das heißen?
Du siehst 153 Zeilen am Stück?
Post by Hermann Riemann
Hermann
der vermutet, dass auch ein 42" 4k_Monitor im Senkrechtbetrieb
mit 9 Pixel Buchstabenhöhe nicht reichen würde.
Ich habe einen 4K-Monitor, und sehe 100 Zeilen am Stück, wenn ich das
Shell-Fenster ganz aufziehe.
--
Mit freundlichen Grüßen
Helmut Schellong ***@schellong.biz
www.schellong.de www.schellong.com www.schellong.biz
http://www.schellong.de/c.htm
Hermann Riemann
2017-03-11 16:28:15 UTC
Permalink
Post by Helmut Schellong
Post by Hermann Riemann
Post by Volker Borchert
Post by Rainer Weikusat
Falls eine Schleife nicht auf eine
Bildschirmseite passt, ist sie entschieden *zu* lang.
Eher ist der Bildschirm zu klein und/oder die Schrift zu groß.
In meiner shell habe ich 153 Zeilen.
Was soll das heißen?
Du siehst 153 Zeilen am Stück?
Nein, es sind auf der Konsole nur 100 Zeilen mit über 950 Spalten
(Font Hack bold Size 10), wenn ich die Breite
auf alle 3 30" Monitore (2560x1600) ausdehne.
Loading Image...
Die 153 war eine momentan Spaltenzahl statt Zeilenzahl
Post by Helmut Schellong
Post by Hermann Riemann
Hermann
der vermutet, dass auch ein 42" 4k_Monitor im Senkrechtbetrieb
mit 9 Pixel Buchstabenhöhe nicht reichen würde.
Ich habe einen 4K-Monitor, und sehe 100 Zeilen am Stück, wenn ich das
Shell-Fenster ganz aufziehe.
Bei einem 24" 4 k Monitore ( etwa höhere Pixeldichte) wären das:

135 Zeilen (>>> 2160*100//1600) bei Wagrechbetrieb ( wie im Bild):
160 Zeilen (>>> 2560*100//1600) bei Senkrechtbetrieb (90° gedreht:)

Hermann
der für newsreader kommentieren, programmieren und
Textberabeitung 3 Monitore für praktisch hält:
der mittlere zum editieren, oft mind. einer für browser.
ein Teil für Konsole. ( bei grep -rn evtl volle Breite)
ansonsten 1/2 Monitore für die *.h Datei.
--
http://www.hermann-riemann.de
Peter J. Holzer
2017-03-11 17:05:33 UTC
Permalink
Post by Hermann Riemann
http://www.hermann-riemann.de/pic/Arbeitsplatz.jpg
Papierloses Büro durch Platzmangel erzwungen? Auch eine Möglichkeit,
würde bei mir aber eher nicht funktionieren.

hp
--
_ | Peter J. Holzer | Fluch der elektronischen Textverarbeitung:
|_|_) | | Man feilt solange an seinen Text um, bis
| | | ***@hjp.at | die Satzbestandteile des Satzes nicht mehr
__/ | http://www.hjp.at/ | zusammenpaßt. -- Ralph Babel
Helmut Schellong
2017-03-11 21:25:58 UTC
Permalink
Post by Hermann Riemann
Post by Helmut Schellong
Ich habe einen 4K-Monitor, und sehe 100 Zeilen am Stück, wenn ich das
Shell-Fenster ganz aufziehe.
160 Zeilen (>>> 2560*100//1600) bei Senkrechtbetrieb (90° gedreht:)
Loading Image...

Ich arbeite lieber mit einem hochauflösenden Monitor
und gvim-Editor, in dem ich bisher bis zu 11 Fenster
gleichzeitig konfiguriert hatte.
--
Mit freundlichen Grüßen
Helmut Schellong ***@schellong.biz
www.schellong.de www.schellong.com www.schellong.biz
http://www.schellong.de/c.htm
Hermann Riemann
2017-03-12 06:28:01 UTC
Permalink
Post by Helmut Schellong
Post by Hermann Riemann
Post by Helmut Schellong
Ich habe einen 4K-Monitor, und sehe 100 Zeilen am Stück, wenn ich das
Shell-Fenster ganz aufziehe.
160 Zeilen (>>> 2560*100//1600) bei Senkrechtbetrieb (90° gedreht:)
http://www.schellong.de/img/kde_desktop.jpg
Ich arbeite lieber mit einem hochauflösenden Monitor
und gvim-Editor, in dem ich bisher bis zu 11 Fenster
gleichzeitig konfiguriert hatte.
Ich verwende mehrere Desktops.
( Spitze war man 3 Monitore a 16 Desktops.)
Leider macht heutzutage kwin meine Fensteranordnung häufig kaputt.
4k geht noch nicht ausreichen ( kvm-switches mögen da eine 60 Hz)
und bei 3 42" Monitore habe ich Platzprobleme.

Wenn ich in C programmiere habe ich meine eigene "xyz.h"
welche neben diversen includes auch Sachen wie
#define bool unsigned char

char *get_text_p(char *c_string);

( Letztere Funktion liefert mir eine Kopie
des strings in einem Puffer zurück.
Die Länge des neuen Puffers wird jedesmal verdoppelt
wenn der Puffer nicht mehr ausreicht,
um im Rest den string noch im Puffer unterzubringen.)

Das Gegenstück xyz.o liegt fest in einem Ordner.

( Das Gleiche für sdl.h sdl.c)

Ich habe auch eine Programm gen_makefile,
welches meine Ordner auf C-Programme durchsucht
und daraus einen Makefile produziert.
Damit vermeide ich u.a. die Tabulatoren im Editor.

Wenn ich in C etwas größeres mache,
habe ich einen Ordner, dessen Name in $HOME/bin erscheinen wird,
eine .h Datei für gemeinsame Daten,
und etliche *.c Dateien.
Und eventuell noch eine *.html datei für die Dokumentation.
Zum Entwickeln brauche ich mind. eine Konsole,
bei Doumentation auch ein browser Fenster,
ein Fenster für *.h
ein (oder mehrere)Fenster für *.c *.html
die einzelnen Dateien haben unterschiedliche Aufgaben.
main.c utility.c init.c ..

xemacs war früher mal ideal.
Leider habe ich bei xemacs keinen gut lesbaren Zeichensatz gefunden.
Mit emacs kann ich nicht die Breite einzelner Unterfenster einstellen,
gvim zeigt nach dem reboot keine Dateiinhalte mehr an,
kate zeigt nur im ersten Unterfenster alle Dateien.

Hermann
der um blättern zu vermeiden gerne viel Textfläche hat.
--
http://www.hermann-riemann.de
Hermann Riemann
2017-03-11 11:54:22 UTC
Permalink
Post by Rainer Weikusat
Schleifen die ich schreiben muss, haben eher regelmaessig als
ausnahmsweise mehr und komplizierteren Initialisierungscode, als man
sinnvollerweise in einer for (;;)-Zeile unterbringen koennte insofern
das syntaktisch ueberhaupt moeglich ist.
Meiner Meinung nach gehört Initialisierungscode,
der nicht die Durchlaufssteuerung ( z.B. Variable i) betrifft,
unmittelbar vor der Schleife.
Wenn es mehr ist, sogar durch Leerzeilen abgetrennt.
Post by Rainer Weikusat
Post by Hermann Riemann
Post by Rainer Weikusat
Selbst wenn man das im ersten Abschnitt von for unterbringen koennte,
sollte man das lieber lassen. Die Baby-Initiasierung und die
Moeglichkeit, dass letzte Statement der Schleife ans Ende ihrer ersten
Zeile zu ziehen ("Wisu denn blus?") machen nur die Bedingung
unkenntlich.
for (int i=0; i<end_wert; i++)
Das halte ich meist für eine bessere Ordnung als irgendwo
im Schleifenrumpf i++ zu "verstecken,
Falls 'Veraendern der Schleifenvariablen' tatsaechlich der letzte
Verarbeitungsschritt einer Schleife ist, kann man das am Ende tun. Das
ist ebenfalls eine feste Position.
Wenn kein continue drin ist.
Wenn die Schleifenvariable in der Schleife geändert wird..
Und man nicht so vergesslich ist, wie ich es bin.
Ansonsten betrachte ich dies als gleichwertig.
( Mit individueller Vorliebe.)

Wenn für der nächsten Iterationsschritt viel zu tun ist,
dann mag das Scheifenende die bessere Stelle sein.
Post by Rainer Weikusat
Post by Hermann Riemann
oder bei einer langen Schleife außerhalb des Sichtbereiches
( Papier andere Seite; Bildschirm >=1 Bild blättern. )
"No reason to put lipstick on a pig". Falls eine Schleife nicht auf eine
Bildschirmseite passt, ist sie entschieden *zu* lang.
Den Scheifeninhalt mit vielen Parameter in Unterprogramme
auslagern erhöht IMHO nicht die Lesbarkeit.

Hermann
der eher for dem Problem steht das er in eine
lange for(i=0,.. Schleife
noch innen drin eine for (i==0,.. Schleife
verwenden möchte,
und dann das äußere i überall in j verwandeln muss.
Weil er i f (etc) für die innerste Schleife verwenden will.
--
http://www.hermann-riemann.de
Peter J. Holzer
2017-03-11 12:20:18 UTC
Permalink
Post by Hermann Riemann
der eher for dem Problem steht das er in eine
lange for(i=0,.. Schleife
noch innen drin eine for (i==0,.. Schleife
verwenden möchte,
und dann das äußere i überall in j verwandeln muss.
Weil er i f (etc) für die innerste Schleife verwenden will.
Ich verwende i, j, k von außen nach innen. Passt zu den
"row-major"-Arrays in C (und den meisten anderen Programmiersprachen
außer Fortran), wo mir a[i][j][k] intuitiver erscheint als a[k][j][i].

Das kann natürlich auch dazu führen, dass man Variablen umbenennen muss,
weil außen eine Schleife dazukommt. Aber oft ist für eine äußere
Schleife ohnehin ein spezifischer Name besser als ein generischer.

hp
--
_ | Peter J. Holzer | Fluch der elektronischen Textverarbeitung:
|_|_) | | Man feilt solange an seinen Text um, bis
| | | ***@hjp.at | die Satzbestandteile des Satzes nicht mehr
__/ | http://www.hjp.at/ | zusammenpaßt. -- Ralph Babel
Claus Reibenstein
2017-03-11 12:24:12 UTC
Permalink
Falls eine Schleife nicht auf eine Bildschirmseite passt, ist sie
entschieden *zu* lang.
Du hast offensichtlich noch nie richtig große Programme geschrieben.

Gruß
Claus
Rainer Weikusat
2017-03-11 13:35:38 UTC
Permalink
Post by Claus Reibenstein
Falls eine Schleife nicht auf eine Bildschirmseite passt, ist sie
entschieden *zu* lang.
Du hast offensichtlich noch nie richtig große Programme geschrieben.
Vermutungen ueber mich sollten hier keine Rolle spielen.

Eine funktionale Einheit in einem Programm (also zB eine Schleife)
sollte so klein sein, dass man sie ueberschauen kann, ohne vorwaerts und
rueckwaerts scrollen zu muessen. Die Sprachmittel dafuer
(Unterprogramme) sind seit mehr als 40 Jahren allgemein vorhanden.

Persoenlich stoert mich das auch nicht, wenn Leute einfach
unsystematisch alles in der Reihenfolge, in der es hoffentlich(!) getan
werden muss, hinter- bzw untereinanderschreiben, aber die normale
Reaktion auf sowas (soweit mir das bekannt ist), ist "wird mit dem
urspruenglichen Autor beerdigt und danach in derselben (Nicht-)from in
einer gerade modernen, anderen Sprache reimplementiert".
Helmut Schellong
2017-03-11 21:02:31 UTC
Permalink
Post by Rainer Weikusat
Post by Claus Reibenstein
Falls eine Schleife nicht auf eine Bildschirmseite passt, ist sie
entschieden *zu* lang.
Du hast offensichtlich noch nie richtig große Programme geschrieben.
Vermutungen ueber mich sollten hier keine Rolle spielen.
Eine funktionale Einheit in einem Programm (also zB eine Schleife)
sollte so klein sein, dass man sie ueberschauen kann, ohne vorwaerts und
rueckwaerts scrollen zu muessen. Die Sprachmittel dafuer
(Unterprogramme) sind seit mehr als 40 Jahren allgemein vorhanden.
Persoenlich stoert mich das auch nicht, wenn Leute einfach
unsystematisch alles in der Reihenfolge, in der es hoffentlich(!) getan
werden muss, hinter- bzw untereinanderschreiben, aber die normale
Reaktion auf sowas (soweit mir das bekannt ist), ist "wird mit dem
urspruenglichen Autor beerdigt und danach in derselben (Nicht-)from in
einer gerade modernen, anderen Sprache reimplementiert".
So etwas ist mir wohlbekannt.
Der nachfolgende Code war bis zu mir ohne eine einzige Funktion vorhanden.
Ich bin ein Strukturierungs- und Struktur-Fan.
=========================================================================
switch (TBT._1s) {
default :
if (!TBT.can_end) {
/* CAN communication with connected devices */
TBT_CANcomm();
}
else TBTcandev_str(0);
//0,64,128,192
if ((TBT._1s&63)==2) ADC.tbt=NS_ADC;
if (ADC.tbt) ADCS1_STRT=1, --ADC.tbt;
else if (ADC.s||ADC.v) ADC.s=ADC.v=0, Init_ADC();
Mess_read_buffs();
break;
case 225:
if (ADC.handler==0) Init_ADC();
ADC.handler=0;
if (Can.bus_off_timer > 0) Can.bus_off_timer--;
else if (Can.bus_off_timer_start) {
Can.bus_off_timer_start= 0;
CSR0= BUS_IRPT_EN; // node transition IRPT enabled
MU.req|=REQ_INITCAN; MU.req_ican|=1;
}
if (Can1.bus_off_timer > 0) Can1.bus_off_timer--;
else if (Can1.bus_off_timer_start) {
Can1.bus_off_timer_start= 0;
CSR1= BUS_IRPT_EN; // node transition IRPT enabled
MU.req|=REQ_INITCAN; MU.req_ican|=2;
}
TBT_check_changed_vars('s');
break;
case 226: if (Modem[0].strt>1) TBTmodem(&Modem[0]);
if (Modem[1].strt>1) TBTmodem(&Modem[1]);
TBT_check_login_timeout();
break;
case 227:
TBTstart_bt_sl_clock_time();
TBTbattest();
TBTbtstore();
break;
case 228: TBTstarkladung();
TBThandsyst(); break;
case 229: if (RDP.enable&&Can.RDP.anz) RDP_tbt();
TBTschwellen_check(); break;
case 230: /*** Auswertung der Isolationsspannung UES ***/
# define K(k) TBTriso(k);
Kx()
# undef K
break;
case 231: /*** Prüfung der Iglr-Verteilung ***/
TBT_reclast(); break;
case 232: /*** Netzspannungen (Karte MMB) ***/
TBTnetz();
TBT_ah();
TBT_temp();
TBT_unsym();
TBT_udiff();
break;
case 233:
TBT_lvdpld();
MU_setevent();
TBTkpzcalc();
break;
case 234: /*** Temperaturkomp. der Ausgangsspannung ***/
/*** Ladestrombegrenzung Ibatt ==> Ured ***/
/*** Sollwert Spannung ***/
TBT_TsenCk();
TBT_tkomp_ured_ugsoll(); break;
case 235: /*** Auswertung der CAN-Kontakte ***/
TBTregis();
TBTcankontakte(); break;
case 236: /*** Auswertung der Digitaleingänge ***/
TBTdigitalinputs();
break;
case 237: TBTgeneral_thres();
TBTbatt_checks();
TBTgegenz();
break;
case 238: TBTalarm_inh_dis(); break;
case 239: TBTsnmp_events(); break;
case 240: TBTrec_events(); break;
case 241: TBTset_events(); break;
case 242: /*** Auswertung Gerätestatus und Zuordnung zu den Meldungen ***/
TBT_set_outputs();
TBTcandev_str(1);
break;
case 243: TBTend();
if (TBT.mkcrc>1) --TBT.mkcrc;
if (MU.flashing&&FL_CS==1) --MU.flashing;
if (Sys.cycles<15) ++Sys.cycles;
break;
}
if (TBT._1s>=225) {
if (Comm.Uer.n>2) Read_Uring(UNE);
if (Comm.Uir.n>2) Read_Uring(UNI);
}
if (++TBT._1s>=244) TBT._1s=0, TBT.can_end=0;
TBTC_TBOF=0; /* IRPT-Auslöser */
return;
}
#pragma noregister
=========================================================================
--
Mit freundlichen Grüßen
Helmut Schellong ***@schellong.biz
www.schellong.de www.schellong.com www.schellong.biz
http://www.schellong.de/c.htm
Volker Borchert
2017-03-12 06:47:57 UTC
Permalink
Post by Helmut Schellong
Der nachfolgende Code war bis zu mir ohne eine einzige Funktion vorhanden.
Ich bin ein Strukturierungs- und Struktur-Fan.
//0,64,128,192
if ((TBT._1s&63)==2) ADC.tbt=NS_ADC;
Gilt hier "if comments and code disagree, both are probably wrong"?
--
"I'm a doctor, not a mechanic." Dr Leonard McCoy <***@ncc1701.starfleet.fed>
"I'm a mechanic, not a doctor." Volker Borchert <***@despammed.com>
Helmut Schellong
2017-03-12 10:55:07 UTC
Permalink
Post by Volker Borchert
Post by Helmut Schellong
Der nachfolgende Code war bis zu mir ohne eine einzige Funktion vorhanden.
Ich bin ein Strukturierungs- und Struktur-Fan.
//0,64,128,192
if ((TBT._1s&63)==2) ADC.tbt=NS_ADC;
Gilt hier "if comments and code disagree, both are probably wrong"?
Nein, &63 funktioniert ja nach jedem Schritt +=64 immer wieder.
--
Mit freundlichen Grüßen
Helmut Schellong ***@schellong.biz
www.schellong.de www.schellong.com www.schellong.biz
http://www.schellong.de/c.htm
Peter J. Holzer
2017-03-12 12:56:37 UTC
Permalink
Post by Helmut Schellong
Post by Volker Borchert
Post by Helmut Schellong
Der nachfolgende Code war bis zu mir ohne eine einzige Funktion vorhanden.
Ich bin ein Strukturierungs- und Struktur-Fan.
//0,64,128,192
if ((TBT._1s&63)==2) ADC.tbt=NS_ADC;
Gilt hier "if comments and code disagree, both are probably wrong"?
Nein, &63 funktioniert ja nach jedem Schritt +=64 immer wieder.
Aber 64 & 63 == 0.

Entweder der Code müsste lauten:
if ((TBT._1s&63)==0) ADC.tbt=NS_ADC;

oder der Kommentar müsste lauten:
// 2, 66, 130, 194

So wie es ist, ist mindestens eine der beiden Zeilen falsch
(möglicherweise beide).

hp
--
_ | Peter J. Holzer | Fluch der elektronischen Textverarbeitung:
|_|_) | | Man feilt solange an seinen Text um, bis
| | | ***@hjp.at | die Satzbestandteile des Satzes nicht mehr
__/ | http://www.hjp.at/ | zusammenpaßt. -- Ralph Babel
Helmut Schellong
2017-03-12 19:18:57 UTC
Permalink
Post by Peter J. Holzer
Post by Helmut Schellong
Post by Volker Borchert
Post by Helmut Schellong
Der nachfolgende Code war bis zu mir ohne eine einzige Funktion vorhanden.
Ich bin ein Strukturierungs- und Struktur-Fan.
//0,64,128,192
if ((TBT._1s&63)==2) ADC.tbt=NS_ADC;
Gilt hier "if comments and code disagree, both are probably wrong"?
Nein, &63 funktioniert ja nach jedem Schritt +=64 immer wieder.
Aber 64 & 63 == 0.
if ((TBT._1s&63)==0) ADC.tbt=NS_ADC;
// 2, 66, 130, 194
So wie es ist, ist mindestens eine der beiden Zeilen falsch
(möglicherweise beide).
Nein, der Kommentar bezieht sich auf '(TBT._1s&63)'.
Er steht ja auch passend drüber.

Alle 6 Bits gesetzt sind immer bei 2^6-1, also 64-1==63.
Gesetzt wird ADC.tbt bei 0+2, 64+2, 128+2, 192+2; 0+2, ...
--
Mit freundlichen Grüßen
Helmut Schellong ***@schellong.biz
www.schellong.de www.schellong.com www.schellong.biz
http://www.schellong.de/c.htm
Peter J. Holzer
2017-03-12 23:12:53 UTC
Permalink
Post by Helmut Schellong
Post by Peter J. Holzer
Post by Helmut Schellong
//0,64,128,192
[...]
Post by Helmut Schellong
Post by Peter J. Holzer
// 2, 66, 130, 194
So wie es ist, ist mindestens eine der beiden Zeilen falsch
(möglicherweise beide).
Nein, der Kommentar bezieht sich auf '(TBT._1s&63)'.
Das kann erst recht nie die Werte 64, 128 oder 192 annehmen.
Post by Helmut Schellong
Er steht ja auch passend drüber.
Alle 6 Bits gesetzt sind immer bei 2^6-1, also 64-1==63.
Gesetzt wird ADC.tbt bei 0+2, 64+2, 128+2, 192+2; 0+2, ...
Und jetzt vergleich das mal mit Deinem und mit meinem Kommentar.

Nein, lass es lieber bleiben. Bringt eh nix.

hp
--
_ | Peter J. Holzer | Fluch der elektronischen Textverarbeitung:
|_|_) | | Man feilt solange an seinen Text um, bis
| | | ***@hjp.at | die Satzbestandteile des Satzes nicht mehr
__/ | http://www.hjp.at/ | zusammenpaßt. -- Ralph Babel
Helmut Schellong
2017-03-13 11:27:52 UTC
Permalink
Post by Peter J. Holzer
Post by Helmut Schellong
Post by Peter J. Holzer
Post by Helmut Schellong
//0,64,128,192
[...]
Post by Helmut Schellong
Post by Peter J. Holzer
// 2, 66, 130, 194
So wie es ist, ist mindestens eine der beiden Zeilen falsch
(möglicherweise beide).
Nein, der Kommentar bezieht sich auf '(TBT._1s&63)'.
Das kann erst recht nie die Werte 64, 128 oder 192 annehmen.
Na und!?
Wieso müssen eventuell in Kommentaren angegebene Konstanten
genau den Ergebniswerten des (Teil-)Ausdrucks darunter entsprechen?
Das allein ist bereits hirnrissig!
Post by Peter J. Holzer
Post by Helmut Schellong
Er steht ja auch passend drüber.
Alle 6 Bits gesetzt sind immer bei 2^6-1, also 64-1==63.
Gesetzt wird ADC.tbt bei 0+2, 64+2, 128+2, 192+2; 0+2, ...
Und jetzt vergleich das mal mit Deinem und mit meinem Kommentar.
Nein, lass es lieber bleiben. Bringt eh nix.
Ich schreibe Kommentare, so wie mir das paßt.
Hauptsache, sie leiten mich später geeignet.

Bei dem Ausdruck '(TBT._1s&63)==2' war mehrmals ein von '2'
unterschiedlicher Wert eingetragen.
Der Kommentar durfte stets unverändert bleiben;
er darf auch bei beliebigen Änderungen der '2' in der Zukunft
unverändert bleiben.
Der Kommentar '//0,64,128,192' paßt hier immer!

Mein Konzept hier ist folglich 'intelligent', während eine
immer wieder anstehende Anpassung des Kommentars ein mehrfach
risikobehafteter, hirnrissiger Blödquatsch wäre.
--
Mit freundlichen Grüßen
Helmut Schellong ***@schellong.biz
www.schellong.de www.schellong.com www.schellong.biz
http://www.schellong.de/c.htm
Peter J. Holzer
2017-03-13 14:55:53 UTC
Permalink
Post by Helmut Schellong
Post by Peter J. Holzer
Post by Helmut Schellong
Post by Peter J. Holzer
Post by Helmut Schellong
//0,64,128,192
[...]
Post by Helmut Schellong
Post by Peter J. Holzer
// 2, 66, 130, 194
So wie es ist, ist mindestens eine der beiden Zeilen falsch
(möglicherweise beide).
Nein, der Kommentar bezieht sich auf '(TBT._1s&63)'.
Das kann erst recht nie die Werte 64, 128 oder 192 annehmen.
Na und!?
Wieso müssen eventuell in Kommentaren angegebene Konstanten
genau den Ergebniswerten des (Teil-)Ausdrucks darunter entsprechen?
Das muss er natürlich nur, wenn er so aussieht, als ob er die möglichen
Ergebniswerte dieses Ausdrucks aufzählen. Das ist hier offensichtlich
für mindestens zwei Leute der Fall.
Post by Helmut Schellong
Post by Peter J. Holzer
Post by Helmut Schellong
Alle 6 Bits gesetzt sind immer bei 2^6-1, also 64-1==63.
Gesetzt wird ADC.tbt bei 0+2, 64+2, 128+2, 192+2; 0+2, ...
Und jetzt vergleich das mal mit Deinem und mit meinem Kommentar.
Nein, lass es lieber bleiben. Bringt eh nix.
Ich schreibe Kommentare, so wie mir das paßt.
Hauptsache, sie leiten mich später geeignet.
Bei dem Ausdruck '(TBT._1s&63)==2' war mehrmals ein von '2'
unterschiedlicher Wert eingetragen.
Der Kommentar durfte stets unverändert bleiben;
er darf auch bei beliebigen Änderungen der '2' in der Zukunft
unverändert bleiben.
Der Kommentar '//0,64,128,192' paßt hier immer!
Er passt meiner Meinung nach nie. Wäre das Code, den ich warten müsste,
würde ich ihn entweder durch etwas ersetzen, was hilft (z.B. die
Information, dass "2" hier keine Konstante ist, sondern immer wieder mal
auf Grund irgendwelcher externen Vorgaben geändert werden muss) oder
ersatzlos löschen.

Wenn Du einen Kommentar brauchst, der dich daran erinnert, was &63
macht, dann ist der Kommentar für Dich natürlich hilfreich. Für mich
wäre er nur irritierend, weil er mir nichts sagt, was für mich beim
Lesen des Codes nicht ohnehin offensichtlich ist, aber dafür etwas zu
sagen scheint, was im offensichtlichen Widerspruch zum Code steht.

hp
--
_ | Peter J. Holzer | Fluch der elektronischen Textverarbeitung:
|_|_) | | Man feilt solange an seinen Text um, bis
| | | ***@hjp.at | die Satzbestandteile des Satzes nicht mehr
__/ | http://www.hjp.at/ | zusammenpaßt. -- Ralph Babel
Hermann Riemann
2017-03-13 09:26:32 UTC
Permalink
Post by Helmut Schellong
Alle 6 Bits gesetzt sind immer bei 2^6-1, also 64-1==63.
Gesetzt wird ADC.tbt bei 0+2, 64+2, 128+2, 192+2; 0+2, ...
Ich finde, Dezimalwerte sind für bit-Arithmetik nicht geeignet.
Da geht hex bei Gewohnheit viel besser,

Am besten wäre Darstellung der Art |..x...x.|x.x..xxx|
die LED-Anzeigen an IO-ports entsprechen.

Hermann
der die Umrechnung lieber dem computer überlässt.
--
http://www.hermann-riemann.de
Helmut Schellong
2017-03-13 11:53:07 UTC
Permalink
Post by Hermann Riemann
Post by Helmut Schellong
Alle 6 Bits gesetzt sind immer bei 2^6-1, also 64-1==63.
Gesetzt wird ADC.tbt bei 0+2, 64+2, 128+2, 192+2; 0+2, ...
Ich finde, Dezimalwerte sind für bit-Arithmetik nicht geeignet.
Da geht hex bei Gewohnheit viel besser,
Am besten wäre Darstellung der Art |..x...x.|x.x..xxx|
die LED-Anzeigen an IO-ports entsprechen.
Nein, es gibt im Zusammenhang noch:
==============================================
static BYTE const u0cmd[256]= {
/* 0*/ 1,
/* 1*/ 2,
/* 2*/ 0,
/* 3*/ 0,
/* 4*/ 3,
/* 5*/ 0,
/* 6*/ 0,
//...
/*252*/ 0,
/*253*/ 0,
/*254*/ 0,
/*255*/ 0,
};
==============================================
und viel weiteren Code.

Der Ausdruck '(TBT._1s&63)==2' stammt aus einem *isolierten* Stück Code,
das AUS GANZ ANDEREN GRÜNDEN (Strukturierung) gepostet wurde!

Es war keine Absicht dabei, detaillierte Analysen ganz anderer Art
zu erlauben.
Wer solche Analysen sinnloserweise trotzdem vornimmt, verhält sich
massiv unprofessionell.
Wer dann auch noch die falschen Resultate der sinnlosen Analyse dazu
verwendet, um angebliche Fehler zu konstruieren, produziert Blödquatsch.
--
Mit freundlichen Grüßen
Helmut Schellong ***@schellong.biz
www.schellong.de www.schellong.com www.schellong.biz
http://www.schellong.de/c.htm
G.B.
2017-03-13 06:41:53 UTC
Permalink
Post by Helmut Schellong
Post by Volker Borchert
Post by Helmut Schellong
Der nachfolgende Code war bis zu mir ohne eine einzige Funktion vorhanden.
Ich bin ein Strukturierungs- und Struktur-Fan.
//0,64,128,192
if ((TBT._1s&63)==2) ADC.tbt=NS_ADC;
Gilt hier "if comments and code disagree, both are probably wrong"?
Nein, &63 funktioniert ja nach jedem Schritt +=64 immer wieder.
Aber (...)
Der Kommentar dokumentiert ja vermutlich die Eigenlogik des Autors.
Er dient nicht der Stützung des unverständigen Lesers: Implikationen,
die sich aus dem Entwurf ergeben, sollte der entsprechend informierte
Leser schon selbst denken können… Vermute ich.
Peter J. Holzer
2017-03-13 07:09:45 UTC
Permalink
Post by G.B.
Post by Helmut Schellong
Post by Volker Borchert
Post by Helmut Schellong
//0,64,128,192
if ((TBT._1s&63)==2) ADC.tbt=NS_ADC;
Gilt hier "if comments and code disagree, both are probably wrong"?
Nein, &63 funktioniert ja nach jedem Schritt +=64 immer wieder.
Aber (...)
Der Kommentar dokumentiert ja vermutlich die Eigenlogik des Autors.
Das hast Du aber hübsch ausgedrückt ;-).

hp
--
_ | Peter J. Holzer | Fluch der elektronischen Textverarbeitung:
|_|_) | | Man feilt solange an seinen Text um, bis
| | | ***@hjp.at | die Satzbestandteile des Satzes nicht mehr
__/ | http://www.hjp.at/ | zusammenpaßt. -- Ralph Babel
Rainer Weikusat
2017-03-13 15:10:11 UTC
Permalink
Post by G.B.
Post by Helmut Schellong
Post by Volker Borchert
Post by Helmut Schellong
Der nachfolgende Code war bis zu mir ohne eine einzige Funktion vorhanden.
Ich bin ein Strukturierungs- und Struktur-Fan.
//0,64,128,192
if ((TBT._1s&63)==2) ADC.tbt=NS_ADC;
Gilt hier "if comments and code disagree, both are probably wrong"?
Nein, &63 funktioniert ja nach jedem Schritt +=64 immer wieder.
Aber (...)
Der Kommentar dokumentiert ja vermutlich die Eigenlogik des Autors.
Er dient nicht der Stützung des unverständigen Lesers: Implikationen,
die sich aus dem Entwurf ergeben, sollte der entsprechend informierte
Leser schon selbst denken können… Vermute ich.
Kommentare sind normalerweise entweder mehr oder minder dummes
Geschwafel ("Fuck me gently with a chainsaw") oder Gedaechtnisnotizen
des Code-Autors, die niemand, der den Code nicht genau versteht, korrekt
interpretieren kann. Vermutlich sind sie ausserdem durch X Generation
von "copy and paste and modify" von der Antarktis in die Sahara
gewandert und haben mit dem momentanen Code genau gar nichts mehr zu
tun.

Volker Borchert
2017-03-12 14:23:08 UTC
Permalink
Post by Helmut Schellong
Post by Volker Borchert
Post by Helmut Schellong
Der nachfolgende Code war bis zu mir ohne eine einzige Funktion vorhanden.
Ich bin ein Strukturierungs- und Struktur-Fan.
//0,64,128,192
if ((TBT._1s&63)==2) ADC.tbt=NS_ADC;
Gilt hier "if comments and code disagree, both are probably wrong"?
Nein, &63 funktioniert ja nach jedem Schritt +=64 immer wieder.
ergäbe aber true bei 2, 66, 130, 194
--
"I'm a doctor, not a mechanic." Dr Leonard McCoy <***@ncc1701.starfleet.fed>
"I'm a mechanic, not a doctor." Volker Borchert <***@despammed.com>
Peter J. Holzer
2017-03-11 15:14:21 UTC
Permalink
Post by Claus Reibenstein
Falls eine Schleife nicht auf eine Bildschirmseite passt, ist sie
entschieden *zu* lang.
Du hast offensichtlich noch nie richtig große Programme geschrieben.
Gerade in "richtig großen" Programmen sollte man darauf achten, die
Einheiten, mit denen ein Programmierer, der einen Bug sucht oder ein
neues Feature einbauen soll, zu tun hat, so übersichtlich wie möglich zu
halten. Wenn ein Wegwerfscript von 300 Zeilen Länge in einer Wurst
runtergeschrieben ist, stört das nicht besonders. Wenn man sich in 80000
Zeilen Java-Code durch 2000 Zeilen lange Methoden durchkämpfen muss,
dann sieht die Sache schon anders aus. Und 80000 Zeilen sind jetzt auch
noch nicht wirklich groß.

hp

PS: "Eine Bildschirmseite" ist natürlich ein sehr grobes Maß. Was heißt
das? 24 Zeilen (klassisches Terminal)? 50 Zeilen (VGA anno 1990)?
86 Zeilen (xterm mit meiner üblichen Schriftgröße)? 147 Zeilen (1920
Pixel vertikal bei dieser Schriftgröße)? Ich halte mich da lieber an
eine A4-Seite, das sind dann bei "normaler" Schriftgröße knapp 70
Zeilen, und das bringe ich auf jedem brauchbaren Monitor auch unter.
--
_ | Peter J. Holzer | Fluch der elektronischen Textverarbeitung:
|_|_) | | Man feilt solange an seinen Text um, bis
| | | ***@hjp.at | die Satzbestandteile des Satzes nicht mehr
__/ | http://www.hjp.at/ | zusammenpaßt. -- Ralph Babel
Hermann Riemann
2017-03-11 17:19:24 UTC
Permalink
Post by Peter J. Holzer
Gerade in "richtig großen" Programmen sollte man darauf achten, die
Einheiten, mit denen ein Programmierer, der einen Bug sucht oder ein
neues Feature einbauen soll, zu tun hat, so übersichtlich wie möglich zu
halten.
In "richtig großen" Programmen weiß man ohnehin oft nicht,
wo was geschieht.

Bei Programmen mit Datenstrukturen hilft da eine gezielt
ansprechbare übersichtliche Ausgabe.
Wert Inhalt, wenn der Inhalt != 0 ist.
bool x oder . statt true false. ..

also if (testbedingung) fprintf(testfile, ..)

Das wäre die erste Näherung,
weil man am Inhalt der Ausgabe schonmal raten kann,
etwas richtig oder falsch sein könnte.
Und man kann mit einem Editor rückwärts suchen.

Hat man das näher eingekreist hilft der Maschinencode trace.
Da kann man sehen wo der falsche Inhalt herkommt.

..

Die bei C interessantesten Fehler sind die,
die bei zusätzlichen printf nicht mehr auftreten,
weil dann irgendein pointer anders ist.
Post by Peter J. Holzer
Wenn ein Wegwerfscript von 300 Zeilen Länge in einer Wurst
runtergeschrieben ist, stört das nicht besonders. Wenn man sich in 80000
Zeilen Java-Code durch 2000 Zeilen lange Methoden durchkämpfen muss,
dann sieht die Sache schon anders aus. Und 80000 Zeilen sind jetzt auch
noch nicht wirklich groß.
Java hab eich nur sehr wenig programmiert und mich aus einigen Gründen
privat von Java verabschiedet.

Die Zeilenzahl alleine sagt noch wenig aus.
Zählt in C die Zeile mit dem einzigen Inhalt { oder }
als Zeile? (In anderen Sprachen "end")
Und dann noch die Leerzeilen?

Hermann
der beruflich viele Zeilen hatte,
und privat, wenn er source code (z.B. den von freeciv)
seinen Bedürfnis anpassen will.
--
http://www.hermann-riemann.de
Volker Borchert
2017-03-11 18:33:30 UTC
Permalink
Post by Hermann Riemann
Die bei C interessantesten Fehler sind die,
die bei zusätzlichen printf nicht mehr auftreten,
weil dann irgendein pointer anders ist.
Zum Beispiel der in realloc() der libc von VMS 5.(5? 4?)
--
"I'm a doctor, not a mechanic." Dr Leonard McCoy <***@ncc1701.starfleet.fed>
"I'm a mechanic, not a doctor." Volker Borchert <***@despammed.com>
kirk
2017-03-11 18:08:53 UTC
Permalink
Post by Peter J. Holzer
runtergeschrieben ist, stört das nicht besonders. Wenn man sich in 80000
Zeilen Java-Code durch 2000 Zeilen lange Methoden durchkämpfen muss,
dann sieht die Sache schon anders aus. Und 80000 Zeilen sind jetzt auch
noch nicht wirklich groß.
Da hast du natürlich Recht. 40 Methoden sind nicht viel für ein "großes Programm".

SCNR,
Enrik
Volker Borchert
2017-03-11 02:06:01 UTC
Permalink
Post by Hermann Riemann
mache_nichts();
ist doch eine richtige Schleife.
Eine Richtigeendlosschleife[TM] geht so ...

PROGRAM MAIN
10 CALL MACHE_NICHTS()
WRITE(*,20)
GOTO 10
20 FORMAT(19HHABE NICHTS GEMACHT)
END

SUBROUTINE MACHE_NICHTS()
WRITE(*,10)
RETURN
10 FORMAT(12HMACHE NICHTS)
END

.. gehört aber nach nebenan.
--
"I'm a doctor, not a mechanic." Dr Leonard McCoy <***@ncc1701.starfleet.fed>
"I'm a mechanic, not a doctor." Volker Borchert <***@despammed.com>
Juergen Ilse
2017-03-11 07:57:17 UTC
Permalink
Hallo,
Post by Volker Borchert
Post by Hermann Riemann
mache_nichts();
ist doch eine richtige Schleife.
Eine Richtigeendlosschleife[TM] geht so ...
PROGRAM MAIN
10 CALL MACHE_NICHTS()
WRITE(*,20)
GOTO 10
20 FORMAT(19HHABE NICHTS GEMACHT)
END
SUBROUTINE MACHE_NICHTS()
WRITE(*,10)
RETURN
10 FORMAT(12HMACHE NICHTS)
END
.. gehört aber nach nebenan.
Warum denn? Bekanntlich koennen (laut dem Artikel "real programmers don't
use pascal") doch "echte Programmierer" in jeder beliebigen Sprache FORTRAN
Programme schreiben ...
;-)

Tschuess,
Juergen Ilse (***@usenet-verwaltung.de)
Hermann Riemann
2017-03-11 11:34:25 UTC
Permalink
Post by Volker Borchert
Post by Hermann Riemann
mache_nichts();
ist doch eine richtige Schleife.
Eine Richtigeendlosschleife[TM] geht so ...
geteste Kurzform.
x(){}main(){ l: x(); goto l;}

Hermann
der als teil-echter Programmierer auch in
C FORTRAN Programmieren kann.
--
http://www.hermann-riemann.de
Helmut Schellong
2017-03-10 10:12:29 UTC
Permalink
Post by Rainer Weikusat
Post by Helmut Schellong
Post by Rainer Weikusat
Post by Helmut Schellong
Post by Rainer Weikusat
while (p) {
next = p->next;
close(p->sock);
p->sock == -1;
Oben 'while (p) {' ist etwas ungewöhnlich.
Warum das?
for (p=sa; p->g; ++p)
for (p=p0; p->nxt; p=p->nxt)
for (;;;)
ist in C eine Art Compiler-Makro dessen Sinn sich mir vollkommen
verschliesst. Richtige Schleifen habe zB Initialisierungs-Anweisungen,
trns = sa->trns;
if (!trns) {
the_trns.enc.type = sa->enctype;
the_trns.enc.len = sa->encklen;
the_trns.hash = sa->hashtype;
the_trns.dhg = sa->dh_group;
the_trns.p = NULL;
trns = &the_trns;
}
t_no = *trns_no;
Selbst wenn man das im ersten Abschnitt von for unterbringen koennte,
sollte man das lieber lassen. Die Baby-Initiasierung und die
Moeglichkeit, dass letzte Statement der Schleife ans Ende ihrer ersten
Zeile zu ziehen ("Wisu denn blus?") machen nur die Bedingung
unkenntlich.
Der Umfang notwendiger Initialisierungen ist variabel.
Initialisierungen können auch aufgeteilt werden.
============================================================================
for (i=0; i<sizeof(*sp); ++i) ((byte*)sp)[i]=0;
for (i=0; i<sizeof(struct stat); ++i) ((byte*)sp)[i]=0;
for (r=0; r<NE(Offs); ++r) Offs[r]=-1;
for (r=0; r<sizeof(Csp00)-1; ++r) {
for (r=0; r<sizeof(Cnam0 )-1; ++r) Cnam[ Cnam0[ r]]=1;
for (r=0; r<sizeof(Cdig0 )-1; ++r) Cdig[ Cdig0[ r]]=1;
for (r=0; r<sizeof(Cifs0 )-1; ++r) Cifs[ Cifs0[ r]]=1;
for (r=0; r<sizeof(Cstrn0)-1; ++r) Cstrn[Cstrn0[r]]=1;
for (r=0; r<sizeof(Cst0 )-1; ++r) Cst[ Cst0[ r]]=1;
for (r=0; r<sizeof(Ccmde0)-1; ++r) Ccmde[Ccmde0[r]]=1;
for (r=0; r<sizeof(Cpipe0)-1; ++r) Cpipe[Cpipe0[r]]=1;
for (r=0; r<sizeof(Cpatt0)-1; ++r) Cpatt[Cpatt0[r]]=1;
for (; n>0L; n-=(long)rn) {
for (; c!=EoF; ) {
for (; C>0; --C,++A) { int l;
for (fn=*A,r=0; (pnt||fn[r]!='='||!r)&&fn[r]&&r<=NAMLEN;
for (; C>0; --C,++A) {
for (; C>0; --C,++A) {
for (opt=0; C>0; --C,++A,opt=0) {
for (; C>0; --C,++A) {
for (; C>0; --C,++A) {
for (; C>0; --C,++A) {
for (; C>0; --C,++A) {
for (; C>0; --C,++A) {
for (o0=A[0]+1,--C,++A; C>0; --C,++A) {
for (m=a=b=0,o=o0; (r=*o)!=0; ++o,m=a=b=0) {
for (p=p0+nck,pe=p0+vsp->lv-1; p<pe; ++p) {
for (r=0; r<l; ++r) {
else for (r=0; r<l; ++r) {
for (r=0; environ[r]; ++r) writef(1, "%s" NL, environ[r]);
for (fn=*A; C>1; --C,++A) {
for (r=0; A[0][r]; ++r);
for (pn=A[0],--C,++A; C>0; --C,++A) {
for (r=0; FuSiz[r]; ++r) {
for (; C>0; --C,++A) { register int n;
for (n=0; r>0; ) {
for (; C>0; --C,++A) {
for (r=1; fn[r]; ++r) {
for (--C,++A; C>0; --C,++A) { int32_t i32; int64_t i64;
for (r=0; r<=NAMLEN&&(fun[r]=A[0][r])!='='&&fun[r]; ++r);
for (r=5; A[0][r]; ++r)
for (r=0; r<sizeof(xrei.meta); ++r)
for (pnt=r=0; r<sizeof(xrei.meta); ++r)
//for (r=0; r<sizeof(xrei.meta); ++r) xrei.meta[r]=0;
for (; C>0; --C,++A) {
for (r=0; r<=NAMLEN&&A[0][r]!='='&&A[0][r]!=':'&&A[0][r];
for (; C>0; --C,++A) {
for (r=0; r<=NAMLEN&&A[0][r]!='='&&A[0][r];
for (nck=r,r=1; A[0][r]; ++r);
for (--r; r>0&&A[0][r]==PNT; --r);
for ( ; r>0&&A[0][r]!=PNT; --r);
for ( ; r>0&&A[0][r]==PNT; --r);
for (r--; r>0&&A[0][r]!=PNT; --r);
for (; C>0; --C,++A) {
for (; C>0; --C,++A) {
for (pnt=C; --pnt>=0; ) {
for (nck=-1,r=C; --r>=0; ) {
for (; C>0; --C,++A) {
for (pn=*A++; --C>0; ++A) {
for ( /*vsp0=vsp*/ ; vsp<vspe&&vsp->p; ++vsp) {
for (np=*A,i=0; (znam[i]=np[i])!='='&&np[i]&&i<=NAMLEN; ++i);
for (; n>0; i+=by,--n) {
for (; vsp<vspe&&vsp->p; ++vsp) {
for (np=vsp->p+la-1; Cdig[*np]; ++np);
for (zp=args,r=0; (qp=aq[r])!=0; ++r) {
for (*zp++='"'; *qp; ++qp,++zp) {
for (i=0; i<NPIPES&&PipPid[i]>0; ++i);
for (s=n=0; n<NPIPES&&PipPid[n]>0; ++n);
for (np=n; np>0; ) {
for (i=0; i<n; ++i) {
for (i=0; i<NPIPES; ++i) PipPid[i]=0;
for (oa=oarg,obits=n=0; *oa; ++oa) {
for (eq=0,oder=1,o=opts; *o; oder<<=1,++o)
for (l=0; nam[l]>='A'&&nam[l]<='Z'; ++l);
for (l=2; l<4&&nam[l]; ++l);
for (; *env; ++env)
for (; *env; *env=env[1],++env);
for (ps=Ps,psx=psnu?Ps2:Ps1; *psx; *ps++ = *psx++) {
for (si=0,s=vcs; (l=*s)>0; ++si,s+=l) {
for (l=0; (c=*s)&&l<sizeof(Cifs0); ++l,++s) {
for (si=0; si<l; ++si) Cifs[Cifs0[si]]=1;
for (bp=buf,l=gkz=kc=c1=0; (c=GET, c!=EoF); c1=c) {
for (fui=0; FuSiz[fui]; ++fui)
for (++ll,ji=0; ji<NJMP&&G.jnams[ji][0]; ++ji)
for (ji=0; G.jtab[ji]; ++ji)
for (; n--; --USi) {
for (fd=e=='e'?2:FdPr; ++fd<sizeof(FDopen); ) {
for (i= USi; i-- >0; close(fd) ) {
for (i=PUSi; i-- >0; close(fd) ) {
for (tblsz=TBLSIZ,i=fd=0; fd<tblsz; ++fd) {
for (i=0; i<NSCREEN; ++i)
case '-': for (i=c=0; c<sizeof(O); ++c)
for (i=0; i<4&&Cdig[c=s[i]=Get()]; ) ++i;
for (i=0; Cnam[n[i]=GET]&&i<=NAMLEN; ++i);
for (i=i0; --gk>0; ) {
for (gz=tz=0,nr=nw; nw>0; nw-=nr) {
for (i=0; i<nr; ) {
for (/*tz=0*/; i<nr&& Cifs[bp[i]]; ++i) if (gz) tz=1;
for ( gz=0 ; i<nr&&!Cifs[bp[i]]; gz=1,Abuf[ap++]=bp[i++]) {
for (gz=tz=0; C>0&&(bp=(*G.cap.a)[G.cap.ai+A], bp); --C,++A) {
for (gz=tz=i=0; i<l; ) {
for (/*tz=0*/; i<l&& Cifs[bp[i]]; ++i) if (gz) tz=1;
for ( gz=0 ; i<l&&!Cifs[bp[i]]; gz=1,Abuf[ap++]=bp[i++]) {
for (fd=nr,nr=2; nr<fd&&(buf[nr]>' '||Cst[buf[nr]]); ++nr)
for ( nr=2; nr<fd&&Cst[buf[nr]]; ++nr);
for ( ; buf[nr]>' '; ++nr,++sb) *sb=buf[nr];
for (cp=vsp->p+vsp->ln; (c=*cp, c); ++cp) {
for (lv=ln-2,c0=*vn,vp=VP; vp<VPe&&vp->p; ++vp) {
for (vp=VP; vp<VPe&&vp->p; ++vp) {
for (vp=VP; vp<VPe&&vp->p; ++vp) {
for (vp=VP; vp<VPe&&vp->p&&vp->ln; ++vp);
for (vp=VP; vp<VPe&&vp->p; ++vp) {
for (c0=*vn++,vp=vap->vp; vp<VPe&&vp->p; ++vp) {
for (vp=VP; vp<VPe&&vp->p; ++vp) {
for (down=0,vpa=vap->vp; vpa<VPe&&vpa->p; ++vpa) {
for (vpb=0,vpa=vap->vp; vpa<VPe&&vpa->p; ++vpa) {
for (pa0=pa=*A; C>0; --C,++A) {
for (pA=*A; *pA; *pa++ = *pA++);
for (sp=Names; sp<Names+sizeof(Names)/sizeof(*Names); ++sp) {
for (i=0; i<sizeof(NameAZ)/sizeof(*NameAZ); ++i) {
for (sp=NameAZ[*nam++]; sp; nam=name,sp=sp->link) {
for (sp=NameAZ[*nam++]; sp; nam=name,sp=sp->link) {
for (++name,sp=sp->link2; sp; sp=sp->link2) {
for (mp=Mem,i=0,wp=p; i<sizeof(Mem)/sizeof(*Mem); ++i,++mp) {
for (i=0; i<M_Args; ++i)
for (mp=Mem,i=0; i<sizeof(Mem)/sizeof(*Mem); ++i,++mp) {
if (sz>0) { for (i=1; mp->sz<<i <= mp->sz+sz; ++i);
for (; i>0; --i,++lp) *lp= 0;
for (bpe=bp=buf,bpe+=nw0; bp<bpe; buf=bp) {
for (i=32; --i>=0; ) {
for (i=32; --i>=0; ) {
for (fd-=30000,i=32; --i>=0; ) {
for (i=0; i<32; ++i) {
for (i=0; i<32; ++i) {
for (; bp<bpe; ++bp) { register byte c;
for (fi=0; fi<16; ++fi)
for (ei=0; ei<ni; ++ei) {
for (ei=0; ei<ni; ++ei) {
for (ei=0; ei<nci; ++ei) pci[ei]= ci;
for (pos.X=pos.Y=0; pos.Y<sz.Y; ++pos.Y) {
for (num=kn=0; l>0; ++bp,--l) {
for (i=0; i<128&&si<len; ++i,++si) {
for (e=e0; *e; ++e) {
for (bp=buf,dp=dirs; (c=*dp, c); ++dp) {
for (; *s; ++s) if (*s==c) return (int)(s-s0)+1;
for (--s; *++s; ) {
for (f=from,t=to; *f; ++f,++t)
for (s1=s,c1=0; *s; c1=*s++) {
for (oc=i=0; i<sizeof(ErrS)/sizeof(*ErrS); ++i)
for (lnu=1; pos<=dpos; ++pos) if (Get()=='\n') ++lnu;
for (c=0; c<nn; ++c)
for (c=0; c<nn; ++c)
for (z0=n=z=0; C>0; --C,++A) { arg=*A;
for (c=0; pA[c]; ++c) {
for (cp=CdDirs; *cp!=FFH; ) {
else if (w<=0) for (ost=0L,w=sizeof(work0),i=0;
for (; C>0; --C,++A) { byte buf[256]; register int lb;
for (lb=i=0; i<w; ++i) { ullong l; byte *s, *f, tb[32];
for (wl=0; wl<7; ++wl)
for (; C>0; --C,++A) {
for (a=buf+l,i=7; --i>=0&&--cn>=0; *a=0) {
for (i=0; i<7; ++i) if (tm[i]<0) tm[i]=tm0[i];
for (bp=buf; *bp; ++bp) {
for (--C,lP=*++A; C>0; --C,lP=*++A) {
for (m=(long double)x,y=2.0; x>2; --x,--m) y*=m;
for (d=2.0,++u; k<n; ++d,++u,++k) D/=d, D*=u;
for (c=n=0; n<sizeof(Fu)/sizeof(*Fu); ++n) {
for (s=i=0; i<sizeof(Fu[0].at)/sizeof(*Fu[0].at); ++i) {
for (a=n=0; n<sizeof(Fu)/sizeof(*Fu); ++n) {
for (c=0,i=0; i<sizeof(Fu)/sizeof(*Fu); ++i) {
for (l=1; l<=NAMLEN&&fnam[l]; ++l);
for (i=fstc[c]-1; i<sizeof(Fu)/sizeof(*Fu); ++i) {
for (pn=ec=i=0; i<sizeof(fu.at)/sizeof(*fu.at)&&fu.at[i]; ++i) {
else for (n=0; (av[i]=*lp++,n<sizeof(along)); ++n,++i);
for (n=0; Cdig[av[i]=*lp++]&&i<avSZ; ++n,++i);
for (n=0; Cdig[av[i]=*lp++]&&i<avSZ; ++n,++i);
for (i=0; e[i]; ++i) if (e[i]=='.'||e[i]=='e'||e[i]=='E') break;
else for (n=0; (av[i]=rGET, n<sizeof(along)); ++n,++i);
for (n=0; Cdig[av[i]=rGET]&&i<avSZ; ++n,++i);
for (n=0; Cdig[av[i]=rGET]&&i<avSZ; ++n,++i);
for (i=0; e[i]; ++i) if (e[i]=='.'||e[i]=='e'||e[i]=='E') break;
else for (n=0; (c=lGET, n<sizeof(long)); ++n)
for (a=A[0]; *a; ++a) {
for (; C>0; --C,++A) {
for (; C>0&&a[0]&&((pm=a[0][0], pm=='-')||
for (endarg=0,i=1; (c=a[0][i], c)||i==1; ++i) {
============================================================================
--
Mit freundlichen Grüßen
Helmut Schellong ***@schellong.biz
www.schellong.de www.schellong.com www.schellong.biz
http://www.schellong.de/c.htm
Claus Reibenstein
2017-03-10 11:01:13 UTC
Permalink
Post by Rainer Weikusat
for (;;;)
Ist syntaktisch falsch. Du meinst sicher: for (;;)
Post by Rainer Weikusat
ist in C eine Art Compiler-Makro dessen Sinn sich mir vollkommen
verschliesst.
Das ist kein Compiler-Makro, sondern eine ganz normale Schleifenanweisung.
Post by Rainer Weikusat
Richtige Schleifen habe zB Initialisierungs-Anweisungen,
trns = sa->trns;
if (!trns) {
the_trns.enc.type = sa->enctype;
the_trns.enc.len = sa->encklen;
the_trns.hash = sa->hashtype;
the_trns.dhg = sa->dh_group;
the_trns.p = NULL;
trns = &the_trns;
}
t_no = *trns_no;
Wo ist da eine Schleife?

Gruß
Claus
Rainer Weikusat
2017-03-10 13:02:23 UTC
Permalink
Post by Claus Reibenstein
Post by Rainer Weikusat
for (;;;)
Ist syntaktisch falsch. Du meinst sicher: for (;;)
Ja.
Post by Claus Reibenstein
Post by Rainer Weikusat
ist in C eine Art Compiler-Makro dessen Sinn sich mir vollkommen
verschliesst.
Das ist kein Compiler-Makro, sondern eine ganz normale
Schleifenanweisung.
Dennis Ritchies "C Reference Manual" definiert

for ( expression-1opt ; expression-2opt ; expression-3opt ) statement

als

expression-1;
while ( expression-2 ) {
statement
expression-3 ;
}

[p. 13]

Das ist eine Texttransformation, somit handelt es sich wenigstens
logisch um ein Makro. C ist hier syntaktisch beschraenkter als Perl,
erlaubt aber trotzdem einigermassen seltsame Konstruktionen:

--------------
#include <stdio.h>

int main(void)
{
int a = 10;

for(puts("Jetzt geht's los.");--a || !puts("Fertig!"); puts("Bleiben sie dran..."))
puts("Wir tun was.");

return 0;
}
Claus Reibenstein
2017-03-10 17:06:32 UTC
Permalink
Post by Rainer Weikusat
Post by Claus Reibenstein
Das ist kein Compiler-Makro, sondern eine ganz normale
Schleifenanweisung.
Dennis Ritchies "C Reference Manual" definiert
for ( expression-1opt ; expression-2opt ; expression-3opt ) statement
als
expression-1;
while ( expression-2 ) {
statement
expression-3 ;
}
Das stimmt aber nur, so lange man kein continue verwendet.
Post by Rainer Weikusat
Das ist eine Texttransformation, somit handelt es sich wenigstens
logisch um ein Makro.
Eben nicht.

Gruß
Claus
Hermann Riemann
2017-03-10 18:12:58 UTC
Permalink
Post by Claus Reibenstein
Post by Rainer Weikusat
Post by Claus Reibenstein
Das ist kein Compiler-Makro, sondern eine ganz normale
Schleifenanweisung.
Dennis Ritchies "C Reference Manual" definiert
for ( expression-1opt ; expression-2opt ; expression-3opt ) statement
als
expression-1;
while ( expression-2 ) {
statement
expression-3 ;
}
Das stimmt aber nur, so lange man kein continue verwendet.
Post by Rainer Weikusat
Das ist eine Texttransformation, somit handelt es sich wenigstens
logisch um ein Makro.
Eben nicht.
Der Preprozesser hätte Schwierigkeiten
Ein compiler baut for, while, do while
in einige if Bedingung bzw true goto um.
und schaut bei Optimierung nach,
wohin er welche Blöcke nach diversen
Abhängigkeitskriterien verschieben kann.

Hermann
der nicht ausschießen mag,
das ein compiler (nicht jeder) bei for(;;);
dafür auch überhaupt keinen code absetzt.
--
http://www.hermann-riemann.de
David Seppi
2017-03-13 11:18:04 UTC
Permalink
Post by Hermann Riemann
Hermann
der nicht ausschießen mag,
das ein compiler (nicht jeder) bei for(;;);
dafür auch überhaupt keinen code absetzt.
... und damit den Code hinter der Endlosschleife ausführbar macht?
Klingt nach einem Compilerfehler.
--
David Seppi
1220 Wien
Helmut Schellong
2017-03-13 12:37:45 UTC
Permalink
Post by David Seppi
Post by Hermann Riemann
Hermann
der nicht ausschießen mag,
das ein compiler (nicht jeder) bei for(;;);
dafür auch überhaupt keinen code absetzt.
... und damit den Code hinter der Endlosschleife ausführbar macht?
Klingt nach einem Compilerfehler.
Welchen Assembler-Code sollte denn auch ein C-Compiler
für »for(;;);« einsetzen?
--
Mit freundlichen Grüßen
Helmut Schellong ***@schellong.biz
www.schellong.de www.schellong.com www.schellong.biz
http://www.schellong.de/c.htm
Rainer Weikusat
2017-03-10 18:28:36 UTC
Permalink
Post by Claus Reibenstein
Post by Rainer Weikusat
Post by Claus Reibenstein
Das ist kein Compiler-Makro, sondern eine ganz normale
Schleifenanweisung.
Dennis Ritchies "C Reference Manual" definiert
for ( expression-1opt ; expression-2opt ; expression-3opt ) statement
als
expression-1;
while ( expression-2 ) {
statement
expression-3 ;
}
Das stimmt aber nur, so lange man kein continue verwendet.
Das das so beschrieben war 'stimmt' unabhaenging von 'continue' und es
illustriert einen wichtigen Punkt,
Post by Claus Reibenstein
Post by Rainer Weikusat
Das ist eine Texttransformation, somit handelt es sich wenigstens
logisch um ein Makro.
Eben nicht.
naemlich den Makro-Aspekt: Es gibt Konventionen fuer die
Benutzung von expression-1opt und expression-3opt gibt (Initialisierung
und Stepping) aber die sind informell: expression-1opt ist eine
Ausdrucksanweisung, die unmittelbar vor Eintritt in die Schleife
ausgewertet werden wird und expression-3opt eine, welche als letzte
Anweisung des Schleifenkoerpers ausgewertet werden wird.

Das Beispielprogramm,

------
#include <stdio.h>

int main(void)
{
int a = 10;

for(puts("Jetzt geht's los.");--a || !puts("Fertig!"); puts("Bleiben sie dran..."))
puts("Wir tun was.");

return 0;
}
------

sollte zur Illustration dieses Sachverhaltes dienen.
G.B.
2017-03-10 18:19:03 UTC
Permalink
Post by Rainer Weikusat
C ist hier syntaktisch beschraenkter als Perl,
--------------
#include <stdio.h>
int main(void)
{
int a = 10;
for(puts("Jetzt geht's los.");--a || !puts("Fertig!"); puts("Bleiben sie dran..."))
puts("Wir tun was.");
return 0;
}
Immerhin geht die Entwicklung C-syntaktischer Sprachen ja
weiter und bringt Ordnung in die Strukturen:

import Foundation

typealias Stepper = (inout Int, Int) -> Void

struct ForLoop : Sequence, IteratorProtocol {

private var a : Int {
didSet {
if a != self.limit { print("Bleiben sie dran...") }
}
}

let limit : Int
private let op : Stepper

func makeIterator() -> ForLoop {
print("Jetzt geht's los.")
return self
}

mutating func next() -> Int? {
self.op(&(self.a), 1)
guard self.a != self.limit else {
print("Fertig!")
return nil
}
return self.a
}

init(initial: Int,
limit: Int,
op: @escaping Stepper)
{
self.limit = limit
self.a = initial
self.op = op
}
}

for _ in ForLoop(initial: 10, limit: 0, op: -=) {
print("Wir tun was.")
}
Rainer Weikusat
2017-03-07 21:42:13 UTC
Permalink
Post by Rainer Weikusat
while (p) {
next = p->next;
close(p->sock);
p->sock == -1;
An den etwas untergegangenen, urspruenglichen Gedanken anknuepfend: ==
anstelle von = ist als Tippfehler aehnlich haeufig. Da C Anweisungen
ohne Seiteneffekte erlaubt, kompiliert solcher Code, obwohl er
hoechswahrscheinlich nicht den Effekt haben wird, den er haben sollte.

Das ist quasi das Gegenstueck zu dem viel haeufiger bemaengelten x =
irgendwas mit Rueckgabewert, das versehentlich in einer Bedingung
landete.
Helmut Schellong
2017-03-09 12:36:21 UTC
Permalink
Post by Rainer Weikusat
An den etwas untergegangenen, urspruenglichen Gedanken anknuepfend: ==
anstelle von = ist als Tippfehler aehnlich haeufig. Da C Anweisungen
ohne Seiteneffekte erlaubt, kompiliert solcher Code, obwohl er
hoechswahrscheinlich nicht den Effekt haben wird, den er haben sollte.
-Wno-dangling-else \
-Wno-logical-op-parentheses \
-Wno-char-subscripts \
-Wno-string-plus-int \
-Wno-bitwise-op-parentheses \
-Wno-parentheses \
-Wno-empty-body \

Ich habe clang wie vorstehend konfiguriert.
Ich kann C und kenne die Operatorenränge.
Deshalb muß ich nicht hunderte Warnungen sehen, darüber, wo ich
absichtlich ohne redundante Klammern schrieb.
--
Mit freundlichen Grüßen
Helmut Schellong ***@schellong.biz
www.schellong.de www.schellong.com www.schellong.biz
http://www.schellong.de/c.htm
G.B.
2017-03-10 07:06:00 UTC
Permalink
Post by Helmut Schellong
Ich kann C und kenne die Operatorenränge.
Deshalb muß ich nicht hunderte Warnungen sehen, darüber, wo ich
absichtlich ohne redundante Klammern schrieb.
Hier denke ich immer an zwei Sorten von Programmen:
- eine Sorte für die peer group, Kleinkunst/Kleinod.
- eine Sorte für Handwerker/Industrieware.

Für die Programme der zweiten Sorte könnte es eine vorteilhafte
Vereinfachung sein, wenn i.W. keinen Operator-Vorrang gäbe.
Rainer Weikusat
2017-03-10 12:51:13 UTC
Permalink
Post by G.B.
Post by Helmut Schellong
Ich kann C und kenne die Operatorenränge.
Deshalb muß ich nicht hunderte Warnungen sehen, darüber, wo ich
absichtlich ohne redundante Klammern schrieb.
- eine Sorte für die peer group, Kleinkunst/Kleinod.
- eine Sorte für Handwerker/Industrieware.
Für die Programme der zweiten Sorte könnte es eine vorteilhafte
Vereinfachung sein, wenn i.W. keinen Operator-Vorrang gäbe.
Konzeptuell sind 'Operatorenraenge' der seltsamen Kurzschrift, die als
Mathematik einigermassen beruechtigt ist, entlehnt. Eine Infix-Notation
derzufolge 1 + 2 * 3 = 9 gaelte, duerfte Verwirrung
stiften. Programmiersprachen, die universell Praefix- oder
Postixnotation benutzen, existieren (Lisp, PostScript, Forth), werden
aber nicht in groesserem Umfang (ausserhalb von Kunsthandwerk) benutzt.

Insofern werden wir wohl mit der wirren Erweiterung der noch viel wirreren
Tradition leben muessen.
Hermann Riemann
2017-03-10 18:18:31 UTC
Permalink
Post by Rainer Weikusat
Konzeptuell sind 'Operatorenraenge' der seltsamen Kurzschrift, die als
Mathematik einigermassen beruechtigt ist, entlehnt. Eine Infix-Notation
derzufolge 1 + 2 * 3 = 9 gaelte, duerfte Verwirrung
stiften. Programmiersprachen, die universell Praefix- oder
Postixnotation benutzen, existieren (Lisp, PostScript, Forth), werden
aber nicht in groesserem Umfang (ausserhalb von Kunsthandwerk) benutzt.
Im compiler intern werden sie schon so benutzt.
Und beim Maschinencode kommt vor der Adressierung auch erst der opcode.

Und dann gibt es noch Taschenrechner.

Hermann
der mit seinem Taschenrechner HP35 mit UPN
(statt 3 * 5: 3 5 * ) diesbezüglich keine Schwierigkeiten hat.
und vermutet, dass es beim eintippen gleich gut ist,
aber nicht beim Lesen.
--
http://www.hermann-riemann.de
Lesen Sie weiter auf narkive:
Loading...