Forum: PC-Programmierung for(;;) bedeutung?


von Mathias (Gast)


Lesenswert?

Hallo,

ich habe hier einen funktionierenden Code mit einer for-Schleife:

1
for(;;) {
2
    if (mc_interface_get_state() == MC_STATE_RUNNING) {
3
      ledpwm_set_intensity(LED_GREEN, 1.0);
4
    } else {
5
      ledpwm_set_intensity(LED_GREEN, 0.2);
6
    }
7
8
    mc_fault_code fault = mc_interface_get_fault();
9
    if (fault != FAULT_CODE_NONE) {
10
11
....

was bedeuten die zwei Semikolon in der Klammer: for(;;) ??

mfg

von physiker (Gast)


Lesenswert?

Das man die Laufzeitvaribel und Abbruchbedingung undefiniert lässt. Ist 
eine (IMHO etwas konfuse) Art eine Endlosschleife zu definieren.

von 4toTakoe (Gast)


Lesenswert?

ist eine Zählschleife ohne Bedingungen. Ist das gleiche wie while(1).

von Dumdi D. (dumdidum)


Lesenswert?

Kann mir jemand erklären wie das aus dem Standard gelesen werden kann? 
Ein leeres Statement evaluiert doch nicht immer zu wahr, oder?

von Oskar (Gast)


Lesenswert?

Dumdi D. schrieb:
> Kann mir jemand erklären wie das aus dem Standard gelesen werden
> kann?
> Ein leeres Statement evaluiert doch nicht immer zu wahr, oder?

Die Abbruchbedingung fehlt -> Endlosschleife

von (prx) A. K. (prx)


Lesenswert?

C99:
6.8.5.3 The for statement
[...]
for ( clause-1 ; expression-2 ; expression-3 ) statement
[...]
Both clause-1 and expression-3 can be omitted. An omitted expression-2 
is replaced by a nonzero constant.

von Rolf M. (rmagnus)


Lesenswert?

physiker schrieb:
> Das man die Laufzeitvaribel und Abbruchbedingung undefiniert lässt. Ist
> eine (IMHO etwas konfuse) Art eine Endlosschleife zu definieren.

Gibt's denn eine weniger konfuse? Bei while muss man immer eine 
Pseudo-Bedingung hinschreiben, während man bei for die Bedingung einfach 
weglassen kann, wenn man keine hat.

von Christopher C. (trihexagon)


Lesenswert?

Rolf M. schrieb:
> physiker schrieb:
>> Das man die Laufzeitvaribel und Abbruchbedingung undefiniert lässt. Ist
>> eine (IMHO etwas konfuse) Art eine Endlosschleife zu definieren.
>
> Gibt's denn eine weniger konfuse? Bei while muss man immer eine
> Pseudo-Bedingung hinschreiben, während man bei for die Bedingung einfach
> weglassen kann, wenn man keine hat.

Vor allem weiß man bei for(;;), dass der Schreiberling auch wirklich 
eine Endlosschleife haben will. Bei while kann es auch ein Versehen 
sein, wegen der Pseudobedingung. Ist alles schon mal vorgekommen...

Deshalb nehme ich lieber for(;;).

von PLonz (Gast)


Lesenswert?

while(FOREVER) {
  ...

von Hannes J. (Firma: _⌨_) (pnuebergang)


Lesenswert?

Christopher C. schrieb:
> Vor allem weiß man bei for(;;), dass der Schreiberling auch wirklich
> eine Endlosschleife haben will. Bei while kann es auch ein Versehen
> sein, wegen der Pseudobedingung. Ist alles schon mal vorgekommen...
>
> Deshalb nehme ich lieber for(;;).

Echt? mit while(true) bist du überfordert?

von Oskar (Gast)


Lesenswert?

Hannes J. schrieb:
> Christopher C. schrieb:
>> Vor allem weiß man bei for(;;), dass der Schreiberling auch wirklich
>> eine Endlosschleife haben will. Bei while kann es auch ein Versehen
>> sein, wegen der Pseudobedingung. Ist alles schon mal vorgekommen...
>>
>> Deshalb nehme ich lieber for(;;).
>
> Echt? mit while(true) bist du überfordert?

Ist das jetzt wirklich ein Grund für einen persönlichen Angriff?
Wegen zwei Wörtchen?
Wirklich?

von (prx) A. K. (prx)


Lesenswert?

Hannes J. schrieb:
> Echt? mit while(true) bist du überfordert?

Naja, am Ende steht oben irgendwo:
#define true 0

von Stefan F. (Gast)


Lesenswert?

> Ein leeres Statement evaluiert doch nicht immer zu wahr, oder?

Ja eben! For Schleifen laufen ja so lange, wie der dritte Ausdruck in 
den Klammern true ist. Und nichts ist immer true, also Endlosschleife.

von (prx) A. K. (prx)


Lesenswert?

Stefan U. schrieb:
> For Schleifen laufen ja so lange, wie der dritte Ausdruck in
> den Klammern true ist.

Ich würde es vorziehen, wenn es der zweite wäre.

> Und nichts ist immer true, also Endlosschleife.

Weil per Standard so festgelegt.

von Paul B. (paul_baumann)


Lesenswert?

Stefan U. schrieb:
> For Schleifen laufen ja so lange, wie der dritte Ausdruck in
> den Klammern true ist.

Das ist wie bei Milli Vanilli:

Girl, you know it's true.

MfG Paul

von Christopher C. (trihexagon)


Lesenswert?

Hannes J. schrieb:
> Christopher C. schrieb:
>> Vor allem weiß man bei for(;;), dass der Schreiberling auch wirklich
>> eine Endlosschleife haben will. Bei while kann es auch ein Versehen
>> sein, wegen der Pseudobedingung. Ist alles schon mal vorgekommen...
>>
>> Deshalb nehme ich lieber for(;;).
>
> Echt? mit while(true) bist du überfordert?

Du willst mich falsch verstehen, oder?

von Tasg (Gast)


Lesenswert?

Bei C macht es doch keinen Sinn, die Syntax der Sprache zu hinterfragen. 
Die ganze Sprache ist unübersichtlich, unlogisch, unsicher und veraltet 
- aber dagegen sehr effizient.

Bei Rust oder Go gibts hier z.B. Konstrukte wie loop { } oder for { } 
für Endlosschleifen.

von Wolfgang (Gast)


Lesenswert?

Mathias schrieb:
> was bedeuten die zwei Semikolon in der Klammer: for(;;) ??

Vermutlich weisst du auch, dass das C-Code ist.

Du darfst eine for-Schleife in C nicht mit for-Schleifen in anderen 
Programmiersprachen verwechseln. In anderen Sprachen wird die Anzahl der 
Durchläufe zusammen mit dem Schlüsselwort FOR festgelegt, d.h. die 
Schleife wird unabhängig von dem, was in der Schleife passiert, eine 
vordefinierte Anzahl von Durchläufen abgearbeitet.
In C wird eine for-Schleife bedingte durch das Abbruchkriterium am 
Anfang der Schleife verlassen. Mit einer definieren Anzahl von 
Durchläufen, wie in anderen Sprachen hat das nichts zu tun.

Und wenn dort kein Abbruchkriterium angegeben ist, läuft sie (per 
default) immer weiter.

von Rolf M. (rmagnus)


Lesenswert?

Wolfgang schrieb:
> Mathias schrieb:
>> was bedeuten die zwei Semikolon in der Klammer: for(;;) ??
>
> Vermutlich weisst du auch, dass das C-Code ist.
>
> Du darfst eine for-Schleife in C nicht mit for-Schleifen in anderen
> Programmiersprachen verwechseln. In anderen Sprachen wird die Anzahl der
> Durchläufe zusammen mit dem Schlüsselwort FOR festgelegt, d.h. die
> Schleife wird unabhängig von dem, was in der Schleife passiert, eine
> vordefinierte Anzahl von Durchläufen abgearbeitet.

Ich würde hier nicht so pauschal von "anderen Programmiersprachen" 
sprechen. In mehreren Sprachen ist es so wie in C. In manchen ist es 
nochmal ganz anders. In Python z.B. iteriert man mit einer for-Schleife 
durch eine Sequenz. Eine Zählschleife, wie du sie beschreibst, gibt es 
da gar nicht.

von Nop (Gast)


Lesenswert?

while (1) finde ich zwar klarer als for(;;) - aber erstens ist die 
for-Variante die von KR empfohlene, und zweitens ist sie der einzige 
Weg, eine Endlosschleife ohne Gemecker durch Lint zu kriegen.

von bastel_ (Gast)


Lesenswert?

Ich bin ja auch für while ( true ). Ist einfach sauberer.
Das (;;) sieht für mich immer wie ein weinender (japanischer) Smiley 
aus, damit finde ich auch gleich zum Ausdruck gebracht, was ich davon 
halte :)

von Rolf M. (rmagnus)


Lesenswert?

bastel_ schrieb:
> Ich bin ja auch für while ( true ). Ist einfach sauberer.

Was soll denn daran sauberer sein, bei einer Schleife, für die man keine 
Bedingung hat, trotzdem eine hinschreiben zu müssen? Die Frage ist ernst 
gemeint. Ich möchte es wirklich gerne verstehen, denn für mich ist eben 
aus dem genannten Grund das for sauberer, da es direkter ausdrückt, 
was ich will - nämlich eine Schleife ohne Bedingung.

von (prx) A. K. (prx)


Lesenswert?

Über Geschmack lässt sich [nicht] streiten.

von physiker (Gast)


Lesenswert?

Regt euch bitte nicht auf und vergesst meine Bemerkung einfach (IMHO und 
so, hätte ich mal nichts gesagt).

von mh (Gast)


Lesenswert?

A. K. schrieb:
> Hannes J. schrieb:
>> Echt? mit while(true) bist du überfordert?
>
> Naja, am Ende steht oben irgendwo:
> #define true 0

Und im for(;;) Fall steht am Ende irgendwo:
#define for(x) while(1){x}

Ist das sinnvoll? Nein! Genausowenig wie #define true 0.

Rolf M. schrieb:
> astel_ schrieb:
>> Ich bin ja auch für while ( true ). Ist einfach sauberer.
>
> Was soll denn daran sauberer sein, bei einer Schleife, für die man keine
> Bedingung hat, trotzdem eine hinschreiben zu müssen? Die Frage ist ernst
> gemeint. Ich möchte es wirklich gerne verstehen, denn für mich ist eben
> aus dem genannten Grund das for sauberer, da es direkter ausdrückt,
> was ich will - nämlich eine Schleife ohne Bedingung.

Das ist meiner Meinung nach Geschmackssache. Für den Einen ist eine 
Endlosschleife eine Schleife ohne Bedingung und für den anderen ist es 
eine Schleife die deren Bedinung immer erfüllt ist. Und die saubere 
Schreibweise für eine Schleife deren Bedingung immer erfüllt ist, ist 
while(true).

von Rolf M. (rmagnus)


Lesenswert?

In Assembler gibt's bedingte Sprünge und unbedingte. Wenn man damit eine 
Endlosschleife machen will, käme aber keiner auf die Idee erst manuell 
ein Flag zu setzen, dann direkt danach mit einem bedingten Sprung zu 
prüfen, ob es gesetzt ist und dann springen. Man würde einfach einen 
unbedingten Sprung hinschreiben. while(true) ist für mich das C-Pendant 
zu ersterem, for(;;) das zu zweiterem.

mh schrieb:
> Und die saubere Schreibweise für eine Schleife deren Bedingung immer
> erfüllt ist, ist while(true).

true ist für mich keine richtige Bedingung, da es von nichts abhängt. 
Dehsalb hatte ich es oben als Pseudobedingung bezeichnet.
Umgangssprachlich würde ich ja auch eher sagen "tue xyz, ohne je 
abzubreuchen" und nicht "tue xyz, solange wahr wahr ist".

von sowaresmal (Gast)


Lesenswert?

Optimierende Compiler gab es früher nicht. Deshalb erzeugte while(1) 
immer einen Test mit Verzweigung. for(;;) tat das nicht. Deshalb ist 
for(;;) die sprachlich optimale Ausdrucksweise.

von (prx) A. K. (prx)


Lesenswert?

Rolf M. schrieb:
> käme aber keiner auf die Idee erst manuell
> ein Flag zu setzen, dann direkt danach mit einem bedingten Sprung zu
> prüfen, ob es gesetzt ist und dann springen.

Sowas ergab bei Transputern mitunter einen Sinn. Deren unbedingter 
Sprung konnte den 3-Register-Stack wegfegen, was der bedingte Sprung 
nicht tat. Folglich gab es Fälle, in denen man damit besser dran war als 
mit dem unbedingten Sprung:
   ldc 0  // push 0
   cj L   // jump if TOS=0
   ...
L: add    // remove the 0

von mh (Gast)


Lesenswert?

Rolf M. schrieb:
> mh schrieb:
>> Und die saubere Schreibweise für eine Schleife deren Bedingung immer
>> erfüllt ist, ist while(true).
>
> true ist für mich keine richtige Bedingung, da es von nichts abhängt.
> Dehsalb hatte ich es oben als Pseudobedingung bezeichnet.
> Umgangssprachlich würde ich ja auch eher sagen "tue xyz, ohne je
> abzubreuchen" und nicht "tue xyz, solange wahr wahr ist".

Dann würdest du auch eher
bool flag;
...
irgendwas passiert mit flag
...
if(flag == true){...}
statt
if(flag){...}
schreiben?

von Rolf M. (rmagnus)


Lesenswert?

mh schrieb:
> Dann würdest du auch eher
> bool flag;
> ...
> irgendwas passiert mit flag
> ...
> if(flag == true){...}
> statt
> if(flag){...}
> schreiben?

Nein, wie kommst du darauf?

von Nop (Gast)


Lesenswert?

Wenn man ein wenig trollen wollte, könnte man natürlich auch in C ein 
Label am Schleifenanfang setzen, zu dem man am Schleifenende dann mit 
GOTO springt.

von c-hater (Gast)


Lesenswert?

Rolf M. schrieb:

> In Assembler gibt's bedingte Sprünge und unbedingte. Wenn man damit eine
> Endlosschleife machen will, käme aber keiner auf die Idee erst manuell
> ein Flag zu setzen, dann direkt danach mit einem bedingten Sprung zu
> prüfen, ob es gesetzt ist und dann springen. Man würde einfach einen
> unbedingten Sprung hinschreiben. while(true) ist für mich das C-Pendant
> zu ersterem, for(;;) das zu zweiterem.

Da ist durchaus was dran.

Der eigentliche Punkt ist aber, dass das Sprachmittel für eine 
offensichtlich bedingungslose Schleife schlicht fehlt und for(;;) nur 
ein sehr nicht-intuitiver Ersatz dafür ist. Eben die typische C-Lösung, 
ursprünglich erzwungen dadurch, daß der Scheiß halt nix anderes als ein 
Makroassembler war.

Und diesem Ursprung haben wir auch solche Stilblüten, wie das von mir 
besonders beliebte Pattern "void function x(void)" zu verdanken. Nur 
C-lover glauben ernsthaft, dass sowas eine Sprache ist...

Die Hälfte der Tastenanschläge geht dafür drauf, irgendwas 
hinzuschreiben, was semantisch absolut keine Funktion hat, nur um die 
Syntax zu befriedigen...

Wenn das nicht vollkommen krank ist, was denn sonst? In sinnvollen 
Sprachen wird das erste void überflüssig durch Einführung eines 
besonderen Schlüsselworts für eine Funktion ohne Result (ich könnte noch 
verstehen, wenn man darauf verzichtet) aber für das zweite void als 
völlig sinnentleerten Parameter gibt es schlicht keine Entschuldigung 
und keine Ausrede. Insbesondere nicht unter dem Aspekt, das ein "void *" 
schon wieder was völlig anderes bedeutet, nämlich gerade nicht, dass 
es keinen Parameter gibt, sondern nur, dass der Typ des übergebenen 
Zeigers nicht bekannt/spezifiziert ist.

Krank, pervers, vollkommen lächerlich. Aber immer noch in Benutzung, 
Jahrzehnte nachdem die Zwänge weggefallen sind, die mal solche Lösungen 
erfordert haben...

von (prx) A. K. (prx)


Lesenswert?

c-hater schrieb:
> aber für das zweite void als
> völlig sinnentleerten Parameter gibt es schlicht keine Entschuldigung
> und keine Ausrede.

Eine historische gibt es. Vor C89 gab es in C bei Funktionsdeklarationen 
keine Parameterdeklarationen. f() war also ein Funktion mit unbekannter 
Anzahl von Parametern unbekannten Typs. Um die Kompatibilität mit altem 
Code nicht zu verlieren musste f(void) her. Das muss man natürlich nicht 
schön finden.

C++ hat damit aufgeräumt, weil die Kompatibilitätsforderung darin nicht 
mehr gegeben war.

> Insbesondere nicht unter dem Aspekt, das ein "void *"
> schon wieder was völlig anderes bedeutet,

Vor C89 gab es keinerlei "void" und die Anzahl Schlüsselwörter wollte 
man nicht beliebig aufblähen - wieder um alte Programme nicht unnötig zu 
behindern.

: Bearbeitet durch User
von Rolf M. (rmagnus)


Lesenswert?

c-hater schrieb:
> Wenn das nicht vollkommen krank ist, was denn sonst? In sinnvollen
> Sprachen wird das erste void überflüssig durch Einführung eines
> besonderen Schlüsselworts für eine Funktion ohne Result

Du willst also das Schlüsselwort, mit dem man in C angibt, dass eine 
Funktion nichts zurückgibt, durch ein Schlüsselwort ersetzen, mit dem 
man angibt, dass die Funktion nichts zurückgibt? Mir erschließt sich der 
Unterschied nicht.

> (ich könnte noch verstehen, wenn man darauf verzichtet) aber für das
> zweite void als völlig sinnentleerten Parameter gibt es schlicht keine
> Entschuldigung und keine Ausrede.

Das ist tatsächlich der Historie und der Kompatibilität zu "früher(tm)" 
geschuldet. In C++ braucht man es dann auch nicht, wobei es optional 
immer noch erlaubt ist - ebenfalls aus Kompatibilitätsgründen.

> Krank, pervers, vollkommen lächerlich. Aber immer noch in Benutzung,
> Jahrzehnte nachdem die Zwänge weggefallen sind, die mal solche Lösungen
> erfordert haben...

Nebenan im Python-Thread beschweren sich manche, dass man die Frechheit 
besessen hat, von Python 2 zu Python 3 die Kompatibilität zu brechen, du 
beschwerst dich, dass C so viele Altlasten mit sich rumschleppt. Man 
kann's halt nicht jedem recht machen.

von temp (Gast)


Lesenswert?

unter C++ gibt es bei while(true) einer Warnung, bei for (;;) nicht. Das 
allein wird der Grund sein es zu verwenden.

von Rene K. (xdraconix)


Lesenswert?

Nop schrieb:
> Wenn man ein wenig trollen wollte, könnte man natürlich auch in C ein
> Label am Schleifenanfang setzen, zu dem man am Schleifenende dann mit
> GOTO springt.

YMMD :-D

von (prx) A. K. (prx)


Lesenswert?

sowaresmal schrieb:
> Optimierende Compiler gab es früher nicht. Deshalb erzeugte while(1)
> immer einen Test mit Verzweigung.

Solche Optimierungen sind kinderleicht, viel einfacher als Optimierung 
von Registernutzung. Weshalb das schon um 1980 herum in C kein Problem 
war.

Rene K. schrieb:
> YMMD :-D

Wobei eine Umstellung der bedingten Schleife auf den Test am Ende damals 
ebenso wenig ein Problem war.
   while(cond) ...
lässt sich trivial als
   jump L
M: ...
L: cond jump M
erzeugen. Und da Konstanten und konstante Ausdrücke in einem C Compiler 
ohnehin schon immer eine Sonderstellung hatten, war die Ersetzung 
eines bedingten durch einen unbedingten Sprung am Ende trivial.

: Bearbeitet durch User
von c-hater (Gast)


Lesenswert?

Rolf M. schrieb:

> Du willst also das Schlüsselwort, mit dem man in C angibt, dass eine
> Funktion nichts zurückgibt, durch ein Schlüsselwort ersetzen, mit dem
> man angibt, dass die Funktion nichts zurückgibt? Mir erschließt sich der
> Unterschied nicht.

Ganz einfach: Eine Funktion, die nichts zurückgibt, ist keine Funktion, 
zumindest nicht im mathematischen Sinn. Entprechende Sprachkonstrukte 
sollten also auch nicht so heißen.

Aber wie schon erwähnt, bin ich hier tatsächlich nicht so streng, weil 
es schließlich nicht wirklich einen Unterschied macht, ob man sich als 
Schlüsselwort einprägt "void function" oder "procedure" oder "sub" oder 
was sonst auch immer noch den Sprachdesignern einfällt.

Bedenklich bei C (und seinen syntaktischen Erben) ist halt die völlig 
willkürliche Bedeutung des "void"-Schlüsselworts in Abhängigkeit vom 
Kontext, die die einfache Lösung (nämlich "void function" einfach als 
ein Schlüsselwort zu betrachten) leider unmöglich macht.

Das ist übrigens nicht nur für Menschen ein Problem, sondern auch für 
den Compiler. Es hält ihn u.U. zumindest davon ab, für ein konkret 
erkanntes syntaktisches Problem eine sinnvolle und zielführende 
Fehlermeldung für den Programmierer liefern zu können...

Solche Probleme liefern auch andere sinnlosen Mehrfachnutzungen von 
Schlüsselwörtern. Sehr deutlich zu bemerken z.B. bei "static" in C++...

Dieselbe Wurzel, dieselbe Seuche. Gespart an Sachen, bei denen überhaupt 
kein Sparzwang besteht...

von Rolf M. (rmagnus)


Lesenswert?

c-hater schrieb:
> Rolf M. schrieb:
>
>> Du willst also das Schlüsselwort, mit dem man in C angibt, dass eine
>> Funktion nichts zurückgibt, durch ein Schlüsselwort ersetzen, mit dem
>> man angibt, dass die Funktion nichts zurückgibt? Mir erschließt sich der
>> Unterschied nicht.
>
> Ganz einfach: Eine Funktion, die nichts zurückgibt, ist keine Funktion,
> zumindest nicht im mathematischen Sinn. Entprechende Sprachkonstrukte
> sollten also auch nicht so heißen.

In imperativen Sprachen sind die wenigsten Funktionen wirklich 
Funktionen im mathematischen Sinne, denn ein ganz wesentliches Element 
sind die "side effects", die den Zustand des Programms ändern. Sowas 
gibt es in mathematischen Funktionen nicht. Und streng genommen geben 
C-Funktionen nicht nichts zurück. void ist ein Datentyp, allerdings sein 
so genannter unvollständiger (ähnlich wie z.B. ein nur deklarierter, 
aber nicht definierter Strukturtyp), d.h. sein Aufbau und Inhalt gelten 
als unbekannt. Und im Prinzip gibt die Funktion dann eben ein Objekt vom 
Typ void zurück. Da er unvollständig ist, kann ich aber nicht selbst ein 
Objekt dieses Typs anlegen und den Rückgabewert diesem zuweisen.

> Bedenklich bei C (und seinen syntaktischen Erben) ist halt die völlig
> willkürliche Bedeutung des "void"-Schlüsselworts in Abhängigkeit vom
> Kontext, die die einfache Lösung (nämlich "void function" einfach als
> ein Schlüsselwort zu betrachten) leider unmöglich macht.

Bis auf Funktionsparameter, wo das void tatsächlich anders verwendet 
wird, ist die Bedeutung eigentlich immer gleich. Auch ein void* ist 
einfach nur ein Zeiger auf den unvollständigen Typ void.

> Das ist übrigens nicht nur für Menschen ein Problem, sondern auch für
> den Compiler. Es hält ihn u.U. zumindest davon ab, für ein konkret
> erkanntes syntaktisches Problem eine sinnvolle und zielführende
> Fehlermeldung für den Programmierer liefern zu können...

Generell macht es die Erstellung eines Compilers aufwändiger. Deshalb 
versucht man heutzutage, in Sprachen Kontextabhängigkeiten möglichst 
gering zu halten.

> Solche Probleme liefern auch andere sinnlosen Mehrfachnutzungen von
> Schlüsselwörtern. Sehr deutlich zu bemerken z.B. bei "static" in C++...

Das ist auch in C schon so.

> Dieselbe Wurzel, dieselbe Seuche. Gespart an Sachen, bei denen überhaupt
> kein Sparzwang besteht...

Man versucht bei so langlebigen Sprachen, die Zahl der Schlüsselwörter 
gering zu halten, da jedes neue Schlüsselwort mehr alte Programme 
inkompatibel macht. Deshalb wird mit diesen in C (und auch in C++) 
besonders sparsam umgegangen - manchmal vielleicht etwas übertrieben, 
aber allgemein trotzdem sinnvoll.

von (prx) A. K. (prx)


Lesenswert?

c-hater schrieb:
> Ganz einfach: Eine Funktion, die nichts zurückgibt, ist keine Funktion,
> zumindest nicht im mathematischen Sinn. Entprechende Sprachkonstrukte
> sollten also auch nicht so heißen.

Da C keine Schlüsselworte für Funktion vs. Prozedur hat, aber auch 
Rechenausdruck und Zuweisung nicht unterschiedlich klassifiziert sind, 
fehlt dieser formellen Unterscheidung schlicht die Grundlage. Das ist in 
Sprachen der Algol/Pascal-Tradition anders - und lesbarer.

Es ist aber müssig, sich heute um solche semantische Feinheiten zu 
streiten. Diese Entscheidung fiel in den 60ern. Es gibt in C so einige 
Dinge, die man im Nachhinein betrachtet besser machen könnte.

Aber gerade diese fehlende formelle Unterscheidung zwischen Funktion und 
Prozedur bietet für mich wenig Anlass für ernste Kritik. Ich kann ganz 
gut damit leben. Ob man schreibt:
  p: procedure(integer);
  f: function(integer) returning integer;
oder (wie es in C besser gewesen wäre):
  p: (int);
  f: (int) int;
ist nur eine Frage von ausführlicher schlüsselwortbetonter Formulierung 
gegenüber knapper Kurzform, aber kein grundsätzlicher Unterschied. Das 
Problem in C ist, dass es leider auch nicht wie diese Kurzform aussieht.

> Bedenklich bei C (und seinen syntaktischen Erben) ist halt die völlig
> willkürliche Bedeutung des "void"-Schlüsselworts in Abhängigkeit vom
> Kontext, die die einfache Lösung (nämlich "void function" einfach als
> ein Schlüsselwort zu betrachten) leider unmöglich macht.

So arg unterschiedlich ist die Bedeutung nicht. "void" steht sinngemäss 
für "nichts", und das passt für alle Formen, wie
  void f(int);   // 1 gibt nichts zurück
  int h(void);   // 2 hat keine Parameter
  void *p;       // 3 zeigt auf keinen Typ
  (void) f(1);   // 4 wirft Ergebnis ins Nichts
Weshalb 2 so aussieht hatte ich schon erwähnt. h() wäre besser gewesen, 
ging aber nicht mehr.

> Das ist übrigens nicht nur für Menschen ein Problem, sondern auch für
> den Compiler. Es hält ihn u.U. zumindest davon ab, für ein konkret
> erkanntes syntaktisches Problem eine sinnvolle und zielführende
> Fehlermeldung für den Programmierer liefern zu können...

Yep. Der Parser einer schüsselwortbetonten Sprache merkt schneller, dass 
er auf dem Holzweg ist, als der Parser einer Sprache, in der fast alles 
irgendwie Sinn ergeben könnte und es erst eine halbe Zeile später 
offenkundig wird. Ein Problem auch von Sprachen ohne reservierte 
Schlüsselworte, wie Fortran oder PL/I.

: Bearbeitet durch User
von Stefan F. (Gast)


Lesenswert?

Mit for() assoziiere ich eine Wiederholschleife, bei der eine 
Zählvariable hoch oder runter gezählt wird. Das ist in C zwar nicht die 
einzige vorgesehene Anwendung, aber zweifellos die häufigste.

Wenn eine Schleife ohne Zählvariable benötigt wird, bevorzuge ich daher 
do/while.

von (prx) A. K. (prx)


Lesenswert?

Stefan U. schrieb:
> Mit for() assoziiere ich eine Wiederholschleife, bei der eine
> Zählvariable hoch oder runter gezählt wird. Das ist in C zwar nicht die
> einzige vorgesehene Anwendung, aber zweifellos die häufigste.

Das ist nun allerdings dein eigenes spezifisches Problem. Vielleicht 
geprägt durch BASIC? (siehe Nachbarthread über die Erstsprache)

Wenn man es etwas abstrakter als Statement für Iteration sieht, dann hat 
man auch kein Problem mit
   for (p = root; p; p = p->next)
und allerlei höheren Varianten in C++. Dazu kommt dann noch, dass man 
(heute) mit
   for (T *p = root; p; p = p->next)
eine übersichtliche Klammer für den Scope von p gleich mit dabei hat.

von Carl D. (jcw2)


Lesenswert?

Mal ketzerisch in die andere Richtung:

Warum soll es einen speziellen, mit eigenem Schlüsselwort versehenen 
Funktionstyp geben, der sich von anderen nur dadurch unterscheidet, daß 
er einen ganz bestimmten Typ, ein "nichts", als Rückgabewert hat?

Braucht man dann nicht auch
[Unsigned][Long]IntFunction(),
[Long]DoubleFunction() oder
CharPointerArrayOfNineReferenceFunction()?

Es gäbe viel zu hassen, wenn sich jemand so blöd gestellt hätte, es zu 
erfinden.

von Rolf M. (rmagnus)


Lesenswert?

A. K. schrieb:
> c-hater schrieb:
>> Ganz einfach: Eine Funktion, die nichts zurückgibt, ist keine Funktion,
>> zumindest nicht im mathematischen Sinn. Entprechende Sprachkonstrukte
>> sollten also auch nicht so heißen.
>
> Da C keine Schlüsselworte für Funktion vs. Prozedur hat, aber auch
> keinen syntaktischen Unterschied zwischen Rechenausdruck und Zuweisung,
> fehlt dieser formellen Unterscheidung schlicht die Grundlage. Das ist in
> Sprachen der Algol/Pascal-Tradition anders - und lesbarer.

Ich habe Pascal vor C gelernt und mich damals gefragt, warum man zwei 
Dinge, die - abgesehen davon, dass eins einen Wert zurückgibt und das 
andere nicht - genau das selbe sind, komplett unterschiedlich benennt.

> Yep. Der Parser einer schüsselwortbetonten Sprache merkt schneller, dass
> er auf dem Holzweg ist, als der Parser eine Sprache, in der fast alles
> irgendwie Sinn ergeben könnte und es erst eine halbe Zeile später
> offenkundig wird. Ein Problem auch von Sprachen ohne reservierte
> Schlüsselworte, wie Fortran oder PL/I.

Lustig ist das bei Sprachen, in denen z.B. Leerzeichen Teil von 
Identifiern sein dürfen. Oder welche, in denen Identifier auch gleich 
heißen dürfen wie Schlüsselwörter. Das gab es alles mal.

Carl D. schrieb:
> Mal ketzerisch in die andere Richtung:
>
> Warum soll es einen speziellen, mit eigenem Schlüsselwort versehenen
> Funktionstyp geben, der sich von anderen nur dadurch unterscheidet, daß
> er einen ganz bestimmten Typ, ein "nichts", als Rückgabewert hat?

Und braucht man dann für eine "Funktion", die keine Parameter hat, noch 
einen weiteren Namen? Und nochmal einen für etwas, das weder Parameter 
noch einen Rückgabewert hat?

Heiner schrieb im Beitrag #4747898:
> hier wird nur noch rumgetrollt.

Eigentlich nur von dir. Wo kommst du denn plötzlich her?

von (prx) A. K. (prx)


Lesenswert?

Carl D. schrieb:
> Warum soll es einen speziellen, mit eigenem Schlüsselwort versehenen
> Funktionstyp geben, der sich von anderen nur dadurch unterscheidet, daß
> er einen ganz bestimmten Typ, ein "nichts", als Rückgabewert hat?
>
> Braucht man dann nicht auch
> [Unsigned][Long]IntFunction(),
> [Long]DoubleFunction() oder
> CharPointerArrayOfNineReferenceFunction()?

Nein. Es ist der Unterschied zwischen einer Funktion
  f: function (...) returning unsigned long int; // oder double oder ...
und einer Prozedur
  p: procedure (...);

Wirklich Sinn ergibt das aber nur, wenn eine Zuweisung eine syntaktische 
eigene Konstruktion ist, und nicht einfach nur ein Rechenausdruck.

In C ist da kein Unterschied. Eine Zuweisung
  a = f(1);
ist einfach nur ein Rechenausdruck, weshalb eben auch
  a = b = f(1); // entspricht a = (b = f(1));
  a = f(b = 1);
möglich ist.

In Sprachen mit getrennten Funktionen und Prozeduren gibt es einerseits 
Zuweisungen:
  <Linkeseite> := <Rechenausdruck>;
und andererseits eben Rechenausdrücke, die nun aber keine Zuweisungen 
enthalten dürfen. In solchen Sprachen sind Prozeduraufrufe eine wiederum 
eigene syntaktische Klasse wie
  p(1);
oder
  call p(1);
und Prozeduraufrufe können in Rechenausdrücken nicht vorkommen. 
Ebensowenig ist in solchen Sprachen
  a + 1;
zulässig, weil ein isolierter Rechenausdruck kein Statement ist.

NB: Da solche Sprachen auch keine impliziten Zuweisungen wie ++/-- 
kennen, tritt in diesen Sprachen das Problem mehrdeutiger 
Interpretationen von
  i = i++ + i++;
überhaupt nicht auf. Dafür fehlt ihnen die für C typische Kurzschrift.

PS: Was ich hier als Syntax anderer Sprachen formuliere, ist grob 
orientiert an Pascal, erhebt aber nicht den Anspruch, wirklich Pascal zu 
sein. Es geht da nur ums Prinzip, nicht um die Details.

: Bearbeitet durch User
von Jan H. (j_hansen)


Lesenswert?

c-hater schrieb:
> Der eigentliche Punkt ist aber, dass das Sprachmittel für eine
> offensichtlich bedingungslose Schleife schlicht fehlt und for(;;) nur
> ein sehr nicht-intuitiver Ersatz dafür ist.

Ich hingegen finde es schön, wenn eine Sprache nicht für jeden 
Sonderfall eine eigene Syntax verlangt. Ich finde den C-Weg auch nicht 
unlogisch, wobei mir persönlich "while(true)" besser gefällt.
Die C-Syntax ist eh schon zu komplex, wenn da noch für jeden Spezialfall 
Befehle hinzukommen würden wäre das ja noch schlimmer.

von Carl D. (jcw2)


Lesenswert?

@A.K.:
Ich hoffe du wolltest nicht meine retorischen Fragen beantworten.
Falls ja können wir gerne die Diskusion in Richtung C++ Features der 
letzten 5 Jahre (11/14) vertiefen. ;-)

von (prx) A. K. (prx)


Lesenswert?

Carl D. schrieb:
> Ich hoffe du wolltest nicht meine retorischen Fragen beantworten.

Und ich hoffe, ich habe dich mit Antworten auf nicht gestellte Fragen 
nicht überfordert. ;-)

von W.S. (Gast)


Lesenswert?

Mathias schrieb:
> was bedeuten die zwei Semikolon in der Klammer: for(;;) ??

Sehr einfach: Sie bedeuten, daß der Schreiber solchen Zeuges einer ist, 
der zu sinnloser Quellcode-Akrobatik neigt.

Formulierungen wie obige oder auch while(1) sind entartete Konstrukte, 
weil sie nichts mehr von ihrem eigentlichen Sinn enthalten. Kein solider 
Programmierer schreibt sowas - nur solche, die sich oberschlau dünken.

In C gibt es massenweise Möglichkeiten, seine innere Sau rauszulassen 
und ne Menge von krudem Zeugs zu schreiben, was durchaus syntaktisch 
völlig in Ordnung ist, aber vom gesunden Menschenverstand, von der 
Wartbarkeit und Lesbarkeit her Bockmist ist.

Rolf M. schrieb:
> Ich habe Pascal vor C gelernt und mich damals gefragt, warum man zwei
> Dinge, die - abgesehen davon, dass eins einen Wert zurückgibt und das
> andere nicht - genau das selbe sind, komplett unterschiedlich benennt.

Weil sie einen völlig unterschiedlichen Sinn haben. Prozeduren sind 
zum Zusammenfassen von Anweisungen zu einem Ganzen gedacht und 
Funktionen zum Liefern eines Ergebnisses.

Sieh es mal ökonomisch: ob man nun function und procedure im 
Sprachschatz hat oder void und ein allgegenwärtiges (), nimmt sich 
nichts. Es macht lediglich letzteres mehr Probleme beim Definieren von 
Funktionstypen.

W.S.

von Operator S. (smkr)


Lesenswert?

@W.S.
Nachdem du nun eine Woche zu spät sagst wie man es nicht macht, möchtest 
du dann nicht etwas für die Menschheit tun und schreiben wie deiner 
Meinung nach eine Endlosschleife in C auszusehen hat? Falls nein, warum 
deine Antwort?

Hochachtungsvoll,

von Erwin D. (Gast)


Lesenswert?

W.S. schrieb:
> Formulierungen wie obige oder auch while(1) sind entartete Konstrukte,
> weil sie nichts mehr von ihrem eigentlichen Sinn enthalten. Kein solider
> Programmierer schreibt sowas - nur solche, die sich oberschlau dünken.

Alle dünken sich also "oberschlau". Jetzt bin ich mal gespannt, was du 
für einen Vorschlag stattdessen hast. Wie sieht deiner Meinung nach eine 
Endlosschleife aus?

von Yalu X. (yalu) (Moderator)


Lesenswert?

W.S. schrieb:
> Formulierungen wie obige oder auch while(1) sind entartete Konstrukte,
> weil sie nichts mehr von ihrem eigentlichen Sinn enthalten.

Auch in deinem geliebten Pascal gibt es für Endlosschleifen nur die
"entarteten" Konstrukte
1
 while true do
2
   begin
3
   end;

und
1
 repeat
2
 until false;

Eine nicht entartete Endlosschleife gibt es nur in den wenigsten
Programmiersprachen, bspw. in Scratch:
1
forever
2
  ...

Dem kommt C mit dem for(;;) noch am nächsten, da die Sprachdesigner hier
zwar kein spezielles Schlüsselwort, aber immerhin eine spezielle Syntax
vorgesehen haben.

von Paul B. (paul_baumann)


Lesenswert?

Yalu X. schrieb:
> Auch in deinem geliebten Pascal gibt es für Endlosschleifen nur die
> "entarteten" Konstrukte
>  while true do
>    begin
>    end;
>
> und
>  repeat
>  until false;

Da ist doch nichts entartet. Das sind Kopf- bzw. fußgesteuerte 
Schleifen, bei denen man EXAKT sieht, wo sie beginnen und enden.

MfG Paul

von Erwin D. (Gast)


Lesenswert?

Paul B. schrieb:
> Da ist doch nichts entartet.

Yalu hat das "entartet" in Gänsefüßchen geschrieben, weil er damit auf 
den Post von W.S. geantwortet hat, der das ohne Gänsefüßchen geschrieben 
hat. :-)

von Carl D. (jcw2)


Lesenswert?

Leute, die keine "entartete Software" mögen, können sich ja ins stramme 
"Überallnetz" zurückziehen. Oder mit ihren "Zerknalltreibling" in's 
Wirthaus fahren.

Man darf seine Worte auch mit etwas mehr Bedacht wählen, denn manche 
sind einfach verbrannt. Oder eben Grundhaltung.

von Paul B. (paul_baumann)


Lesenswert?

Carl D. schrieb:
> Man darf seine Worte auch mit etwas mehr Bedacht wählen, denn manche
> sind einfach verbrannt. Oder eben Grundhaltung.

Man kann sich einfach nicht von Irgendjemandem vorschreiben lassen, 
welche Worte man vor lauter Korrektheit nicht mehr verwenden darf. So 
lange der Zusammenhang dadurch klarer und deutlicher wird, sehe ich 
keinen Grund, auf altbekannte Worte zu verzichten, oder gar in das 
allseits beliebte DENGLISCH zu verfallen.

MfG Paul

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Paul B. schrieb:
> Man kann sich einfach nicht von Irgendjemandem vorschreiben lassen,
> welche Worte man vor lauter Korrektheit nicht mehr verwenden darf.

Doch. Vom eigenen Gewissen. Hat man keins, ist man natürlich leicht 
raus.

von Paul B. (paul_baumann)


Lesenswert?

Rufus Τ. F. schrieb:
> Doch. Vom eigenen Gewissen.

Teufel, Mariette! Gewissen?! -Du lieber Himmel! Geht's nicht ein wenig 
undramatischer?

Kopf schüttel

-Paul-

von W.S. (Gast)


Lesenswert?

Operator S. schrieb:
> wie deiner
> Meinung nach eine Endlosschleife in C auszusehen hat?

sehr einfach:

immerzu:


goto immerzu;

Also, ein entartetes Konstrukt ist eines, dessen ursprünglicher 
Sinngehalt nicht vorhanden ist.
Bei einem
1
while (bedingung) tu_dies;

ist das eben die Bedingung, die die Definition einer bedingten Schleife 
in der Sprachdefinition notwendig gemacht hat. Wäre da nicht die 
Notwendigkeit, einer Bedingung im Programmlauf zu entsprechen, dann wäre 
das Wort "while" völlig überflüssig - und zwar in jeder 
Programmiersprache.

Das Gleiche gilt für die "for" Schleife. Der gedachte Zweck ist es, eine 
gleiche Operation auf verschiedene abzählbare Elemente ausüben zu 
können.

Nimmt man dem while seine Bedingung oder dem for seine Abzählung, dann 
entartet man damit dieses Sprachelement. Es ist für solchen Zweck nicht 
vorgesehen - obwohl man es syntaktisch so benutzen kann (aber beileibe 
nicht muss).

Das Konstrukt aus marke und goto ist hingegen exakt für unbedingte 
Sprünge und somit für derartige unbedingte Schleifen vorgesehen.

Kapito?

So, nochwas zu den dümmlichen Bemerkungen zum Begriff "Entartet":
Hier gibt es ganz offensichtlich naturwissenschaftlich ungebildete 
Dummköpfe. Ja, Dummköpfe! Ich spreche nicht von Unwissenden, sondern von 
Leuten, die zwar etwas nicht wissen, aber dennoch übelgemeinte 
Bemerkungen ablassen welche an Unterstellungen grenzen. Den Begriff der 
Entartung kennt man in den Naturwissenschaften seit Fermi. Schaut mal 
per Google nach "Entartete Materie". Auch die Riemannsche Fläche ist im 
Ursprung entartet. Ich sag's mal so: Wer da bildungsmäßig außen vor ist, 
soll sich gefälligst böswillige Äußerungen verkneifen.

W.S.

von Nop (Gast)


Lesenswert?

W.S. schrieb:
> immerzu:
>
> goto immerzu;

Hab ich weiter oben auch schon vorgeschlagen - zum Trollen. Praktisch 
gesehen kann man damit aber prüfen, ob das Codereview gründlich 
durchgeführt wird.

von P. M. (mikro23)


Lesenswert?

1
for(;;)

ist für mich nur die Abkürzung für:
1
for(i = 0; i < ; i++)

Das ist eine reguläre EndlosSCHLEIFE.

von D. I. (Gast)


Lesenswert?

P. M. schrieb:
> for(i = 0; i < ∞; i++)

wie wärs mit:
1
uint32_t i = 0;
2
for(i = 0; i <= (uint32_t) 0xFFFFFFFF; i++);

;)

von Nase (Gast)


Lesenswert?

Auf BeOS würde man das einfach so lösen:
1
while (is_computer_on()) {
2
3
}

http://www.tycomsystems.com/beos/bebook/the%20kernel%20kit/system.html

von Rolf M. (rmagnus)


Lesenswert?

W.S. schrieb:
> Also, ein entartetes Konstrukt ist eines, dessen ursprünglicher
> Sinngehalt nicht vorhanden ist.
> Bei einem
> while (bedingung) tu_dies;
>
> ist das eben die Bedingung,

Der ursprüngliche Sinngehalt von while und for ist erstmal die 
wiederholte Ausführung eines Stück Code. Da man diese Wiederholung meist 
an eine Bedingung knüpfen möchte, hat man das gleich mit eigebaut. Die 
unbedingte Ausführung der Schleife kann man nun einfach als Spezialfall 
der bedingten Schleife sehen.

> Wäre da nicht die Notwendigkeit, einer Bedingung im Programmlauf zu
> entsprechen, dann wäre das Wort "while" völlig überflüssig - und zwar in
> jeder Programmiersprache.
>
> Das Gleiche gilt für die "for" Schleife. Der gedachte Zweck ist es, eine
> gleiche Operation auf verschiedene abzählbare Elemente ausüben zu
> können.
>
> Nimmt man dem while seine Bedingung oder dem for seine Abzählung, dann
> entartet man damit dieses Sprachelement.

Nein, man hat einfach nur einen Spezialfall bzw. Trivialfall, sonst 
nichts. Ein
1
printf("Hello world");
ist für mich auch keine entartete Verwendung von printf(), nur weil im 
Formatstring keine Format-Anweisungen stehen und es danach keine 
weiteren Parameter gibt. Die braucht man eben in diesem Fall nicht.

> Es ist für solchen Zweck nicht vorgesehen - obwohl man es syntaktisch so
> benutzen kann (aber beileibe nicht muss).

Wenn man für jeden Spezialfall immer extra noch was vorsehen würde, 
wären die Sprachen noch aufgeblähter, ohne dass daraus irgendein Nutzen 
entstehen würde.

> Das Konstrukt aus marke und goto ist hingegen exakt für unbedingte
> Sprünge und somit für derartige unbedingte Schleifen vorgesehen.

Für mich sind for und while die Konstrukte, die in C für Schleifen 
vorgesehen sind. Goto dagegen eher nicht. Ist für dich sowas wie:
1
if (bedingung)
2
    goto sprungziel;
auch eine entartete Verwendung von goto, da es deiner Aussage nach ja 
nur für unbedingte Sprünge vorgesehen ist und durch das if jetzt aber 
ein bedingter Sprung draus gemacht wird? Bräuchte man ein goto_if 
(bedingung, sprungziel) um diesen Makel der Sprache zu beheben?

von (prx) A. K. (prx)


Lesenswert?

D. I. schrieb:
> wie wärs mit:

Geht bei 64-Bit ints in die Hose. UINT_MAX wär besser.

von D. I. (Gast)


Lesenswert?

A. K. schrieb:
> D. I. schrieb:
>> wie wärs mit:
>
> Geht bei 64-Bit ints in die Hose. UINT_MAX wär besser.

uint32_t sind auf 64bit 64bit breit? Das wäre mir jetzt aber neu.

von (prx) A. K. (prx)


Lesenswert?

Stimmt, das war Unsinn.

UINT_MAX ist aber trotzdem besser.

von Wegstaben V. (wegstabenverbuchsler)


Lesenswert?

Nase schrieb:
> Auf BeOS würde man das einfach so lösen:while (is_computer_on()) {
>
> }

Dazu braucht man kein BeOS
das kannst du dir auch in C so definieren:

#define is_computer_on true
#define die_erde_sich_um_die_sonne_dreht true

-->

while (is_computer_on) { ... }
while (die_erde_sich_um_die_sonne_dreht) { ... }

von (prx) A. K. (prx)


Lesenswert?

PS: ... meinte natürlich UINT32_MAX.

von D. I. (Gast)


Lesenswert?

A. K. schrieb:
> PS: ... meinte natürlich UINT32_MAX.

Ja da bin ich dabei ;)

von vorticon (Gast)


Lesenswert?

Ihr habt aber auch spass alle zusammen mit diesen total konstruktiven 
Diskussionen hier was?

W.S. schrieb:
> Sehr einfach: Sie bedeuten, daß der Schreiber solchen Zeuges einer ist,
> der zu sinnloser Quellcode-Akrobatik neigt.

W.S. schrieb:
> Kein solider
> Programmierer schreibt sowas - nur solche, die sich oberschlau dünken.

W.S. schrieb:
> Kapito?

c-hater schrieb:
> Wenn das nicht vollkommen krank ist, was denn sonst?

Carl D. schrieb:
> Es gäbe viel zu hassen, wenn sich jemand so blöd gestellt hätte, es zu
> erfinden.

Ich bin jetzt mal ganz mutig und bringe was GANZ KONTROVERSES in die 
Debatte ein (ist aber ernst gemeint und wirklich so!)

Also hier die von mir haeufig benutzte Codefloskel:

if(0) {
...
}

Warum? Weil es schneller geht als auszukommentieren!
(Ja, ich weiss, es gibt auch multi-line-Kommentare. Aber nicht in allen 
Programmiersprachen, und manchmal weiss man nicht mehr, wie man die 
schreibt, und und und)...

von npn (Gast)


Lesenswert?

vorticon schrieb:
> Also hier die von mir haeufig benutzte Codefloskel:
>
> if(0) {
> ...
> }

kicher...:-D

Hast du jetzt die "if-schleife" erfunden?
Oder warum bringst du jetzt die Zeilen, wenn es um Endlosschleifen geht?

von Jemand (Gast)


Lesenswert?

vorticon schrieb:
> Warum? Weil es schneller geht als auszukommentieren!
> (Ja, ich weiss, es gibt auch multi-line-Kommentare. Aber nicht in allen
> Programmiersprachen, und manchmal weiss man nicht mehr, wie man die
> schreibt, und und und)...

Hat auch den Vorteil, dass man solche „Kommentare“ verschachteln kann. 
Amateursprachen wie C können das ja nicht von Haus aus.

Ich nutze da aber dennoch lieber die Blockkommentarfunktion meiner IDE.

von ◔͜͡◔ ~. (Gast)


Lesenswert?

Tasg schrieb:
> Bei C macht es doch keinen Sinn, die Syntax der Sprache zu hinterfragen.
> Die ganze Sprache ist unübersichtlich, unlogisch, unsicher und veraltet
> - aber dagegen sehr effizient.

Unübersichtlich: Wenn man die Syntax nicht versteht, ist jede Sprache 
unübersichtlich. Und ich empfinde C als einfach.

Unlogisch: Inwiefern ist die Sprache unlogisch? Logik wird doch durch 
den Programmierer entwickelt.

Unsicher: Eine Programmiersprache ist nicht unsicher, sondern ihre 
Laufzeitumgebung. Wenn du mit C einen Puffer Überlauf provozierst ist 
das die Schlampigkeit des Programmierer und nicht eine Unsicherheit der 
Sprache. Vielleicht gibt es Szenarien in denen es sogar gewollt ist, in 
einem Speicherbereich zu schreiben der nicht der eigene ist? (Shared 
Memory)

Veraltet: Alt ist nicht veraltet. Ein etwas hinkendes Beispiel:
Windows ist auch alt, ist Windows deshalb veraltet? Nein.
C als auch Windows werden kontinuierlich weiterentwickelt bzw. 
standardisiert.

Effizient: Ja. Gibt aber auch andere effiziente(re) Sprachen (z.B: 
Assembler). Und Effizienz ist auch eine Sache des Programmierer.

Jeder Sprache hat Ihre Vor- und Nachteile.
Durch Gebashe ohne Argumente wird eine Sprache deshalb nicht autom. 
schlecht.

von vorticon (Gast)


Lesenswert?

npn schrieb:
> Hast du jetzt die "if-schleife" erfunden?
> Oder warum bringst du jetzt die Zeilen, wenn es um Endlosschleifen geht?

Hier geht es ja laengst nicht mehr um die while-Schleife, sondern um 
alles und nichts. da fand ich es passend ;)

von (prx) A. K. (prx)


Lesenswert?

◔͜͡◔ ~. schrieb:
> Unsicher: Eine Programmiersprache ist nicht unsicher, sondern ihre
> Laufzeitumgebung.

Die Sprache definiert, was die Laufzeitumgebung kontrollieren kann und 
was nicht. So ist es in C per Sprachdefinition nicht möglich, 
routinemässig bei Array-Zugriffen auf gültige Index-Grenzen zu prüfen. 
Daher ist in diesem Sinn nicht die Laufzeitumgebung unsicher, sondern 
tatsächlich die Sprache.

> Vielleicht gibt es Szenarien in denen es sogar gewollt ist, in
> einem Speicherbereich zu schreiben der nicht der eigene ist?

Eine auf Sicherheit bedachte Sprache wird das als Ausnahmefall sehen und 
dafür spezielle Mechanismen bereitstellen. Der Regelfall sind dann 
abgesicherte Zugriffe. Denn im Regelfall wird so etwas eben nicht 
benötigt.

C ist in hohem Mass nach dem Prinzip "Schrott rein Schrott raus" 
konzipiert. Und es ist vom Anspruch durchdrungen, dass Programmierer 
perfekte Wesen sind, die keine Fehler machen.

Dies darf spätestens seit dem Internet-Zeitalter als gründlich 
gescheitert gelten. Vielmehr müsste es darum gehen, nicht allein vom 
Programmierer eine sichere Programmierung zu verlangen. Sondern man 
sollte ihm Werkzeuge zur Verfügung stellen, die das Ausmass an 
Programmierfehlern so weit reduzieren, wie es jeweils sinnvoll möglich 
ist. C ist kein solches Werkzeug.

: Bearbeitet durch User
von Nop (Gast)


Lesenswert?

A. K. schrieb:
> C ist in hohem Mass nach dem Prinzip "Schrott rein Schrott raus"
> konzipiert.

C ist wie die Suzuki Bandit 600. Ja, sie rostet schon im Prospekt. Aber 
Du kriegst nirgendwo mehr Wums pro Euro.

von Sheeva P. (sheevaplug)


Lesenswert?

c-hater schrieb:
> Der eigentliche Punkt ist aber, dass das Sprachmittel für eine
> offensichtlich bedingungslose Schleife schlicht fehlt und for(;;) nur
> ein sehr nicht-intuitiver Ersatz dafür ist. Eben die typische C-Lösung,
> ursprünglich erzwungen dadurch, daß der Scheiß halt nix anderes als ein
> Makroassembler war.

Kannst Du endlich mal aufhören, jeden C-Thread mit Deinem ideologischen 
Scheiß voll zu müllen? Danke.

von vmni (Gast)


Lesenswert?

A. K. schrieb:
> So ist es in C per Sprachdefinition nicht möglich,
> routinemässig bei Array-Zugriffen auf gültige Index-Grenzen zu prüfen.

Und doch existieren entsprechende Funktionen zur Array Verarbeitung die 
auch die Länge überprüfen.
https://de.wikibooks.org/wiki/C-Programmierung:_Sicherheit

Ausserdem musst du in jeder Programmiersprache prüfen ob die 
eingegebenen Daten plausibel sind und überhaupt zur Weiterverarbeitung 
taugen. In diesem Schritt lässt sich auch die Länge prüfen bevor aus 
stdin in das Array geschrieben wird.

von Rolf M. (rmagnus)


Lesenswert?

vorticon schrieb:
> Also hier die von mir haeufig benutzte Codefloskel:
>
> if(0) {
> ...
> }
>
> Warum? Weil es schneller geht als auszukommentieren!

Ich würde da aber den Präprozessor nutzen:
1
#if 0
Vorteil: Unterscheidet sich optisch besser vom normalen Programm, und in 
dem damit ausgeklammerten Teil können auch Fehler sein, die 
normalerweise nicht durch den Compiler gingen. Das ist vor allem 
praktisch, wenn man von wo anders Code einsetzt und den da drin Schritt 
für Schritt zum laufen bringen will. Es kommt dann nicht gleich ein 
Fehler, nur weil in noch nicht "scharf geschaltetem Code" z.B. eine noch 
fehlende Funktion aufgerufen wird.

A. K. schrieb:
> C ist in hohem Mass nach dem Prinzip "Schrott rein Schrott raus"
> konzipiert.

Schrott bleibt Schrott, auch in anderen Sprachen. Der Gewinn bei dem 
Prinzip "Schrott rein, Edelschrott raus" ist nicht so hoch, wie viele zu 
glauben scheinen. Eine Sprache, die das, was du geschrieben hast, 
automatisch durch das ersetzt, was du eigentlich hättest schreiben 
sollen, gibt es noch nicht.

> Und es ist vom Anspruch durchdrungen, dass Programmierer perfekte Wesen
> sind, die keine Fehler machen.

Es gibt in C einige Fehler, die man in manch anderen Sprachen nicht 
machen kann oder nicht so leicht macht. Und es gibt Fehler, die man auch 
in anderen Sprachen machen kann und die dort leichter vertuscht werden 
können.

A. K. schrieb:
> ◔͜͡◔ ~. schrieb:
>> Unsicher: Eine Programmiersprache ist nicht unsicher, sondern ihre
>> Laufzeitumgebung.
>
> Die Sprache definiert, was die Laufzeitumgebung kontrollieren kann und
> was nicht. So ist es in C per Sprachdefinition nicht möglich,
> routinemässig bei Array-Zugriffen auf gültige Index-Grenzen zu prüfen.

Wo steht denn in der Sprachdefinition, dass die Laufzeitumgebung keine 
Index-Grenzen prüfen darf?

von (prx) A. K. (prx)


Lesenswert?

vmni schrieb:
> Und doch existieren entsprechende Funktionen zur Array Verarbeitung die
> auch die Länge überprüfen.

Ich sehe keinen Zusammenhang zwischen dieser Aussage und den Inhalten 
vom Link. Es geht mir um Arrays allgemein und die werden darin nicht 
einmal erwähnt.

So gibt es in C keine Möglichkeit, einer Funktion als Parameter ein 
Array zu übergeben. In der Funktion ist das kein Array mehr, die 
Information über die Länge ist nicht mehr vorhanden. Dass der 
Programmierer diese Länge separat übergeben und Zugriffe zu Fuss prüfen 
kann ist kein gleichwertiger Ersatz dafür.

> Ausserdem musst du in jeder Programmiersprache prüfen ob die
> eingegebenen Daten plausibel sind und überhaupt zur Weiterverarbeitung
> taugen.

Selbstverständlich sollte man vom Programmierer verlangen, dass er 
fehlerfrei programmiert. Solange diese Strategie aber noch nicht 
zufriedenstellend durchsetzbar ist, sollte man immerhin etwas mithelfen, 
indem man ihm Werkzeuge zur Verfügung stellt, die zumindest manche 
Programmierfehler ausbügeln.

Daher ist neben es neben der Forderung an den Programmierer, keine 
Fehler zu machen, trotzdem sinnvoll, zur Laufzeit zu kontrollieren, ob 
er wirklich keinen Fehler gemacht hat. Dort, wo das mit einfachen 
Mitteln möglich ist. Und das setzt eine Sprache voraus, in der das geht.

von (prx) A. K. (prx)


Lesenswert?

Rolf M. schrieb:
> Wo steht denn in der Sprachdefinition, dass die Laufzeitumgebung keine
> Index-Grenzen prüfen darf?

Ersetze "darf" durch "kann". C99: In 6.7.5.3.7 beispielsweise: "A 
declaration of a parameter as ‘‘array of type’’ shall be adjusted to 
‘‘qualified pointer to type’"

Es ist nur dort überhaupt möglich, wo die Längeninformation direkt als 
Teil des Arrays vorliegt. Mit Übergabe an eine Funktion geht diese 
Information verloren. Ebensowenig ist es möglich, ein Array dynamisch 
anzulegen und Zugriffe darauf implizit zu kontrollieren.

Allgemein gesagt gibt es keinen Weg, eine Referenz auf ein Array 
irgendwo zu speichern, bei der die Längeninformation irgendwie als Teil 
der Referenz implizit erhalten bleibt. Dort, wo der ursprüngliche Name 
eines Arrays nicht mehr direkt verwendet wird, sind Indexgrenzen nicht 
mehr implizit prüfbar.

: Bearbeitet durch User
von (prx) A. K. (prx)


Lesenswert?

Rolf M. schrieb:
> Schrott bleibt Schrott, auch in anderen Sprachen. Der Gewinn bei dem
> Prinzip "Schrott rein, Edelschrott raus" ist nicht so hoch, wie viele zu
> glauben scheinen.

Betrachte Edelschrott == kontrollierter Programmabsturz. ;-)

> Eine Sprache, die das, was du geschrieben hast,
> automatisch durch das ersetzt, was du eigentlich hättest schreiben
> sollen, gibt es noch nicht.

Es geht nicht um den do what I mean, not what I say Compiler, sondern um 
die Frage, was im Falle eines Falles passiert. Eine index out of bounds 
exception, die ein Programm abschmieren lässt, ist bei einem buffer 
overflow die bessere Reaktion, als seelenruhig weiter zu machen.

Man kann selbstverständlich nicht jeden Programmierfehler derart 
ausbügeln. Aber in diesem Fall kann man es in anderen Sprachen bereits 
seit Äonen. In C kann man es nicht.

: Bearbeitet durch User
von P. M. (mikro23)


Lesenswert?

D. I. schrieb:
> wie wärs mit:
> uint32_t i = 0;
> for(i = 0; i <= (uint32_t) 0xFFFFFFFF; i++);

1
for(uint8_t i = 0; i <= 0xFF; i++)

braucht auf dem µC weniger Speicher ;)

von Kaj G. (Firma: RUB) (bloody)


Lesenswert?

A. K. schrieb:
> C ist in hohem Mass nach dem Prinzip "Schrott rein Schrott raus"
> konzipiert.
"Wenn du eine Funktion mit Scheisse fuetterst, darfst du nicht erwarten, 
dass am Ende Rosen dabei rauskommen."
Ganz Ehrlich: Das finde ich sogar richtig so. Der Programmierer hat sich 
verdammt nochmal gedanken zu machen, was er da macht.

A. K. schrieb:
> Sondern man
> sollte ihm Werkzeuge zur Verfügung stellen, die das Ausmass an
> Programmierfehlern so weit reduzieren, wie es jeweils sinnvoll möglich
> ist. C ist kein solches Werkzeug.
C selbst nicht, aber es gibt genug andere Werkzeuge die vor einer Menge 
moeglicher Fehler und Gefahren warnen. Das faengt schon bei den 
Warnungen des Compilers an. Gerade fuer C/C++ gibt es so viele Werkzeuge 
wie fuer keine andere Sprache. Man muss diese Tools aber auch nutzen 
wollen !
Und da scheitert es nicht an der Sprache oder den Tools, sondern faengt 
bei dem Programmierer selbst an, der so eingebildet ist und meint, dass 
er keine Fehler macht, und geht weiter ueber Fuehrungsebenen die nicht 
genug Zeit einraeumen um Dinge vernuenftig zu Testen.

Um nur mal ein paar dieser Werkzeuge und Methoden zu nennen:
- Valgrind
- CppCheck
- PC-Lint
- Splint
- Unittest
- Fuzzing
- Warnungen des Compilers
- CLang mit seinen Sanitizer-Flags & Co.

Werkzeuge sind mehr als genug vorhanden. Es fehlt aber das Bewustsein 
und die Bereitschaft,
- sich selbst einzugestehen das man Fehler macht
- diese Tools auch nutzen zu wollen !

Neben Fehlern wie einem Speicherueberlauf, sind Logikfehler (glaube ich) 
das viel groessere Problem (wobei man da jetzt streiten kann, ob ein 
Speicherueberlauf aus einem Logikfehler resultiert und damit (indirekt) 
auch ein Logikfehler ist). Und gerade diese beiden Fehler kann man sehr 
gut mit Unittests und Fuzzing finden. Ach nee, dass muesste man ja 
wieder wollen !

Unittests/Fuzzing und Tester/Hacker machen nichts kaputt, sie zeigen, 
dass es schon immer kaputt war.
Solange aber Entwickler angst haben, das jemand aussenstehendes den Code 
besser versteht als sie selbst, und sie angst davor haben, das jemand 
ihr heiliges Kind anfaesst und womoeglich kaputt macht (wie man auch 
immer Code kaputt machen koennen sollte erschliesst sich mir nicht), und 
das finden und aufzeigen von Fehlern als persoenlicher Angriff gewertet 
wird, wird sich nie etwas andern.

Der Mensch (oder besser: seine Eitelkeit und seine Einblidung, dass er 
das non-plus-ultra der Schoepfung ist) ist das Problem, nicht die 
Werkzeuge, die er geschaffen hat.

Ich finde es traurig wie die Schuld immer von einem selbst auf die 
Sprache geschoben wird (das ist bei C so, das ist bei PHP so, und es 
gibt bestimmt noch einen ganzen Sack voll).

Wenn ihr euch mit einem Hammer auf dem Finger haut, dann schreit ja auch 
keiner danach, dass man Haemmer verbieten sollte, weil soooo 
gefaerhlich. Entweder ihr meidet absofort den Gebrauch eines Hammers, 
oder ihr macht euch schlau, wie man es besser macht... oder ihr lasst 
alles beim alten und heult beim naechsten mal wieder.

Die Schuld, dass ihr euch auf dem Finger gehauen habt, liegt aber nicht 
beim Werkzeug, sondern bei euch.
Bei der Programmierung scheint es aber voellig normal zu sein, Fehler 
und Probleme, die aus der falschen Benutzung resultieren, immer auf das 
Tool zu schieben. Ist ja so schoen einfach und angenehm... Man selbst 
macht ja keine Fehler, das Tool ist einfach nur scheisse.

Wenn ihr C ach so scheisse findet, dann nutzt es doch einfach nicht. 
Ach, ihr verdient euer Geld damit? Dann kuendigt doch einfach und sucht 
euch Arbeit, wo ihr C meiden koennt, Gaertner zum Beispiel.
Entwickelt doch eure eigene Sprache, die ganz toll super duper fancy 
ist, und all die Fehler aller anderen Sprachen nicht macht...

Hoert auf zu heulen und macht es besser, oder haltet doch endlich mal 
die Klappe. Ich bin es echt leid...
Meckern und heulen ist ja so schoen einfach, aber aendern will dann doch 
keiner was. Muesste man ja Zeit und Arbeit investieren... Nee, da heult 
man lieber weiter rum und missioniert das Sprache XY ach so scheisse 
ist, weil man sich damit in beide Knie, den linken Fuss und den rechten 
Ellbogen geschossen hat... das man aber bei der Benutzung Fehler gemacht 
hat wird natuerlich verschwiegen, oder aber es wird schoen geredet:
"Also das konnte ja keiner wissen... und deswegen ist die Sprache 
scheisse."

Abgesehen davon, hat das alles schon lange nichts mehr mit dem Thread zu 
tun.

So, und jetzt schmier ick mir ne Stulle, setzt mich auf den Balkon und 
geniesse die Sonne!

von Rolf M. (rmagnus)


Lesenswert?

A. K. schrieb:
> Rolf M. schrieb:
>> Wo steht denn in der Sprachdefinition, dass die Laufzeitumgebung keine
>> Index-Grenzen prüfen darf?
>
> Ersetze "darf" durch "kann". C99: In 6.7.5.3.7 beispielsweise: "A
> declaration of a parameter as ‘‘array of type’’ shall be adjusted to
> ‘‘qualified pointer to type’"
>
> Es ist nur dort überhaupt möglich, wo die Längeninformation direkt als
> Teil des Arrays vorliegt.

Oder dort, wo man vom Array wieder auf die Länge kommen kann.

> Mit Übergabe an eine Funktion geht diese Information verloren.
> Ebensowenig ist es möglich, ein Array dynamisch anzulegen und Zugriffe
> darauf implizit zu kontrollieren.

Warum? Gerade bei dynamischen Arrays weiß die Laufzeitumgebung die Größe 
sehr wohl. Ohne das könnte man dynamischen Speicher gar nicht sinnvoll 
implementieren.

> Allgemein gesagt gibt es keinen Weg, eine Referenz auf ein Array
> irgendwo zu speichern, bei der die Längeninformation irgendwie als Teil
> der Referenz implizit erhalten bleibt.

Warum sollte das nicht gehen? Sowas wurde durchaus auch gemacht:
https://staff.aist.go.jp/y.oiwa/FailSafeC/index-en.html

> Dort, wo der ursprüngliche Name eines Arrays nicht mehr direkt verwendet
> wird, sind Indexgrenzen nicht mehr implizit prüfbar.

Für dich ist alles unmöglich, für das dir auf die Schnelle keine 
Möglichkeit einfällt, oder?

von Yalu X. (yalu) (Moderator)


Lesenswert?

Rolf M. schrieb:
> Ich würde da aber den Präprozessor nutzen:
> #if 0

Ich auch :)

> Vorteil: Unterscheidet sich optisch besser vom normalen Programm,

In einigen Editoren und IDEs wird der damit umschlossene Codeabschnitt
sogar als Kommentar gehighlightet.

> und in dem damit ausgeklammerten Teil können auch Fehler sein, die
> normalerweise nicht durch den Compiler gingen.

Man kann damit auch komplette Funktionen, globale Deklarationen,
Makrodefinitionen u.v.m. auskommentieren, was mit if(0) alles nicht
möglich ist.

Rolf M. schrieb:
> A. K. schrieb:
>> C ist in hohem Mass nach dem Prinzip "Schrott rein Schrott raus"
>> konzipiert.
>
> Schrott bleibt Schrott, auch in anderen Sprachen. Der Gewinn bei dem
> Prinzip "Schrott rein, Edelschrott raus" ist nicht so hoch, wie viele zu
> glauben scheinen.

Das Ziel bei den "besseren" Sprachen ist es weniger, auf Schrott etwas
Gutes zu machen, sondern

1. die Folgen der schrottigen Programmierung in überschaubaren Grenzen
   zu halten oder

2. potentiellen Schrott gar nicht erst zu ermöglichen.

Punkt (1) geschieht typischerweise durch Lauffzeitprüfungen, die das
Programm im Fehlerfall einfach abbrechen, bevor Schlimmeres passiert.
Nur ist ein Programmabbruch nicht in allen Anwendungsfällen eine
akzeptable Lösung, da "nichts tun" manchmal genauso fatal wie "das
Falsche tun" ist.

Punkt (2) geschieht durch restriktivere Sprachkonzepte wie bspw.
- Verzicht auf Zeigerarithmetik
- strengere Typprüfung
- andere Programmierparadigmen wie bspw. die funktionale Programmierung,
  wo sich logische Programmfehler (sofern sie überhaupt syntaktisch
  möglich sind) oft in einer anderen, leichter zu prüfenden Fehlerart
  (bspw. Typfehlern) niederschlagen.

Wo diese Punkte nicht anwendbar sind, weil die die einzusetzende
Programmiersprache fest vorgegeben ist, kann versucht werden, mittels
zusätzlicher Tools zur statischen Codeanalyse potentiellen Schrott als
solchen zu erkennen und abzuweisen.

Alle genannten Möglichkeiten reduzieren zwar die Wahrscheinlichkeit von
Fehlern oder deren Folgen, Softwareentwicklung ganz ohne Mitdenken des
Programmierers wird es aber vermutlich nie geben :)


Rolf M. schrieb:
> https://staff.aist.go.jp/y.oiwa/FailSafeC/index-en.html

Interessantes Projekt, werde ich mir mal etwas genauer anschauen.

von Christopher C. (trihexagon)


Lesenswert?

◔͜͡◔ ~. schrieb:
> Tasg schrieb:
>> Bei C macht es doch keinen Sinn, die Syntax der Sprache zu hinterfragen.
>> Die ganze Sprache ist unübersichtlich, unlogisch, unsicher und veraltet
>> - aber dagegen sehr effizient.
>
> Unübersichtlich: Wenn man die Syntax nicht versteht, ist jede Sprache
> unübersichtlich. Und ich empfinde C als einfach.

Funktionszeiger.

A. K. schrieb:
>> Vielleicht gibt es Szenarien in denen es sogar gewollt ist, in
>> einem Speicherbereich zu schreiben der nicht der eigene ist?
>
> Eine auf Sicherheit bedachte Sprache wird das als Ausnahmefall sehen und
> dafür spezielle Mechanismen bereitstellen. Der Regelfall sind dann
> abgesicherte Zugriffe. Denn im Regelfall wird so etwas eben nicht
> benötigt.

Stichwort "unsafe block" in C# oder Rust.

◔͜͡◔ ~. schrieb:
> Veraltet: Alt ist nicht veraltet. Ein etwas hinkendes Beispiel:
> Windows ist auch alt, ist Windows deshalb veraltet? Nein.
> C als auch Windows werden kontinuierlich weiterentwickelt bzw.
> standardisiert.

Inwiefern wurde C seit Ansi-C (1989) weiterentwickelt? Man hat ein paar 
nette und nützliche Dinge hinzugefügt, aber das wars schon. Kein 
Vergleich zu anderen Sprachen oder gar zu Windows.

A. K. schrieb:
> Dies darf spätestens seit dem Internet-Zeitalter als gründlich
> gescheitert gelten. Vielmehr müsste es darum gehen, nicht allein vom
> Programmierer eine sichere Programmierung zu verlangen. Sondern man
> sollte ihm Werkzeuge zur Verfügung stellen, die das Ausmass an
> Programmierfehlern so weit reduzieren, wie es jeweils sinnvoll möglich
> ist. C ist kein solches Werkzeug.

Ich verstehe bis heute nicht wie man sicherheitskritische Software wie 
OpenSSL heutzutage in C schreiben kann. Mit C fliegt man früher oder 
später gehörig auf die Schnauze, egal wie sorgfältig man versucht zu 
sein.

Kaj G. schrieb:
> Ich finde es traurig wie die Schuld immer von einem selbst auf die
> Sprache geschoben wird (das ist bei C so, das ist bei PHP so, und es
> gibt bestimmt noch einen ganzen Sack voll).

? So einfach ist es nicht. Programmiersprachen sind nicht für 
gottgleiche Wesen geschaffen worden sondern für Menschen. Eine Maschine 
die durch einen sehr einfachen Bedienfehler großen Schaden anrichtet, 
hat das Ziel verfehlt, menschgerecht bedienbar zu sein. Man kann einem 
Menschen schwer vorwerfen, ein Mensch zu sein.

Kaj G. schrieb:
> Um nur mal ein paar dieser Werkzeuge und Methoden zu nennen:
> - Valgrind
> - CppCheck
> - PC-Lint
> - Splint
> - Unittest
> - Fuzzing
> - Warnungen des Compilers
> - CLang mit seinen Sanitizer-Flags & Co.

MISRA-C hast du noch vergessen. Es ist unglaublich, welch ein Aufwand 
betrieben wird um C sicher zu machen. Lieber kämpft man 40 Jahre weiter 
mit so einer Sprache, anstatt das man mal ein Werkzeug nutzt, dass die 
gewünschte Sicherheit von selbst garantiert und Mechanismen bietet diese 
explizit auszuschalten. Ist das schon Dekadenz?

von W.S. (Gast)


Lesenswert?

Rolf M. schrieb:
> Der ursprüngliche Sinngehalt von while und for ist erstmal die
> wiederholte Ausführung eines Stück Code. Da man diese Wiederholung meist
> an eine Bedingung knüpfen möchte...

Genau umgekehrt wird ein Schuh draus. Der ursprüngliche Sinngehalt 
aller derartiger Schlüsselwörter in einer Programmiersprache ist das 
Behandeln einer Bedingung. Das ist für do..while, while.. und if eben 
die logische Bedingung und für for die gleichartige Behandlung mehrere 
Variablen etc.

Nochmal zum Mitschreiben: Es sind Schlüsselwörter, die zum bedingten 
Ausführen von irgendwas in der Sprache benötigt werden. So herum.

Versuche doch mal, dir ein if vorzustellen ohne eine Bedingung ("Da 
man diese Wiederholung MEIST an eine Bedingung knüpfen möchte.."). 
Siehst du? Nix da von wegen "meist" -  sonst kommt Mumpitz dabei heraus: 
'if' ohne eine Bedingung ist so ein Mumpitz.

Nochwas:
Rolf M. schrieb:
> Ist für dich sowas wie:
> if (bedingung)
>     goto sprungziel;
> auch eine entartete Verwendung von goto

Hast du das Denken verlernt? Das was du da grad geschrieben hast, ist 
unlogisch. Die korrekte Generalform in C ist
1
if (bedingung) anweisung;
und du versuchst hier grad, mit Krampf ein if (bedingung).. als eine 
Variante von goto umzudeuten. Was soll das?

W.S.

von W.S. (Gast)


Lesenswert?

◔͜͡◔ ~. schrieb:
> Unübersichtlich: Wenn man die Syntax nicht versteht, ist jede Sprache
> unübersichtlich. Und ich empfinde C als einfach.

Was du empfindest, ist deine Gewöhnungssache. Tatsächlich ist C 
unübersichtlich. Warum? Weil in C extrem an menschlich lesbaren 
Schlüsselwörtern gespart wurde und stattdessen mit sonstigen Satzzeichen 
in unterschiedlichster Kombination gearbeitet wird.
Beispiel gefällig?   *  *A */ X*A X**A A*
Andere Programmiersprachen sind da wesentlich übersichtlicher, da von 
hause aus besser lesbar. Sowas wie begin und end versteht selbst ein 
totaler Laie auf Anhieb.

> Unlogisch: Inwiefern ist die Sprache unlogisch? Logik wird doch durch
> den Programmierer entwickelt.

Nö. Manche Sprachen sind tatsächlich logisch aufgebaut (wie Pascal oder 
Algol) und C ist eben nicht logisch aufgebaut, sondern diktatorisch. 
So nach dem Motto "hier wird das eben so gemacht, basta!"
Beispiel:
warum wurde das Gleichheitszeichen als Zuordnungsoperator mißbraucht, wo 
doch seit Erfindung der Mathematik selbiges als Gleichheitszeichen 
bereits vergeben ist und an allen Ecken bei C zusammengesetzte Zeichen 
üblch sind? Fehlentscheidung! Und die zieht weiteren Mumpitz nach sich, 
wie z.B. A==B

Oder warum  muß der Ausdruck nach if denn in eine Klammer? Es gibt doch 
gar nichts zu klammern!
bei einem Term  (A+B)*C ist klar, daß hier Klammern sein müssen, sonst 
ginge die Rechnung falsch. Aber wozu bei einem if ? Bloß, um sowas wie 
ein then zu vermeiden?

Oder wozu bei
1
if (CharAvailable()) c = GetChar();
die leeren Klammern, wo doch von vornherein feststeht, daß die 
betreffenden Funktionen gar keine Argumente benötigen? Wenn man die 
Adresse einer Funktion benötigen würde, dann hätte man das auch per 
@CharAvailable oder @GetChar implementieren können. Gleiches hätte 
gelten können für die Adresse von Variablen, das hätte dann einige & 
wegrationalisiert, was der Lesbarkeit förderlich wäre, denn & ist ja 
bereits anderweitig belegt.
Wurde aber verschlampt.

Das sind nur einige Beispiele von Unlogik in C, die durch einen 
unlogischen Grundentwurf dieser Sprache verursacht wurden - und nie 
beseitigt wurden.

> Unsicher: Eine Programmiersprache ist nicht unsicher, sondern ihre
> Laufzeitumgebung. Wenn du mit C einen Puffer Überlauf provozierst ist
> das die Schlampigkeit des Programmierer und nicht eine Unsicherheit der
> Sprache. Vielleicht gibt es Szenarien in denen es sogar gewollt ist, in
> einem Speicherbereich zu schreiben der nicht der eigene ist? (Shared
> Memory)

Ja, die  ubiquitären Pufferüberläufe auf dem Stack. Seit Jahrzehnten ein 
beliebtes Tor für Viren.
Aber das ist es nicht, was C unsicher macht. Es ist die immanente 
Unlogik dieser Sprache. Ganz viele Programmierer haben heftige 
Schwierigkeiten, das auszudrücken, was sie eigentlich bezwecken wollen. 
Formuliere doch mal ein const array von Zeigern, die jeweils auf 
verschiedene const arrays von irgendwelchen Daten oder auf Funktionen 
zeigen. Ist mangels dedizierter Typdeklarationen ein Stück 
Hochtrapez-Turnerei, fehleranfällig und unleserlich.

Die Sprache macht es den Programmierern schwer, da sie keinerlei 
Sauberkeit kennt. Da wird lustig zwischen Typdefinitionen, 
Variablendeklarationen und Code gewuselt, ohne selbige sauber zu 
trennen, selbst Konstantendefinitionen lassen sich nur per Präprozessor 
- also außerhalb der eigentlichen Programmiersprache erledigen.
Man vergleiche mal mit Pascal:
const var type label

jaja, wenn eine Sprache von vornherein ein bissel für Ordnung sorgt, 
dann kommt auch mehr an Sicherheit dabei heraus.

> Veraltet: Alt ist nicht veraltet. Ein etwas hinkendes Beispiel:
> Windows ist auch alt, ist Windows deshalb veraltet? Nein.
> C als auch Windows werden kontinuierlich weiterentwickelt bzw.
> standardisiert.

Ja, C ist tatsächlich veraltet. Es kennt sehr vieles nicht, was 
mittlerweile dringend benötigt wird, weil sich die Welt inzwischen 
weitergedreht hat. Also z.B. Objektorientierung, echte weiterführende 
Datentypen, Strings, Exceptions - um nur ein paar zu erwähnen.

Den Treppenwitz mit sowas wie "uint32_t" und Konsorten, die erstens 
unleserlich sind und zweitens überhaupt nicht im Compiler verankert 
sind, sondern per Headerdatei auf das alte schlichte unsigned long int 
zurückgeführt werden, bevor der eigentliche Compiler sie zu fressen 
kriegt, kenne wir ja zur Genüge.

Ist eben auch Mumpitz.
Aber warum?
Nun, weil die eingefleischten C-Leute nicht mehr fähig sind, 
irgendwelche echten Neuerungen in die Sprache einzuführen. Das ist 
zugegebenerweise auch schwierig, da der ursprüngliche Sprachentwurf eben 
zu unlogisch war, deshalb an zu vielen Stellen ein "das ist hier eben 
so!" steht und damit jede Neuerung mit dem Aufbrechen alten Unfugs 
verbunden wäre.

Kurzum: C is nicht mehr renovierungsfähig. Man kann damit leben, in 
vielen Gebieten wie µC-Programmierung muß man das auch mangels Tools für 
andere Sprachen und C reicht eigentlich auch für recht vieles völlig 
aus, aber eine wirklich gute Programmiersprache ist C wahrlich nicht.

> Effizient: Ja. Gibt aber auch andere effiziente(re) Sprachen (z.B:
> Assembler). Und Effizienz ist auch eine Sache des Programmierer.

Ja, beipflicht. Man kann in C durchaus effizient und leserlich 
schreiben, aber das gilt auch für andere Programmiersprachen genauso - 
sofern selbige kein interpretatives Laufzeitsystem erfordern, sondern 
echten Maschinencode erzeugen.

W.S.

von ◔͜͡◔ ~. (Gast)


Lesenswert?

> Christopher C. schrieb:
> Inwiefern wurde C seit Ansi-C (1989) weiterentwickelt? Man hat ein paar
> nette und nützliche Dinge hinzugefügt, aber das wars schon. Kein
> Vergleich zu anderen Sprachen oder gar zu Windows.
C11 ersetzt C99.
Inwiefern die Änderungen einen Fortschritt darstellen... Man mag die 
Frage mal rumdrehen: Braucht es einen Fortschritt? Oder gibt es derzeit 
keinen Verbesserungsbedarf für C? Ich glaube eher nicht.

> A.K. schrieb:
Ich sehe keinen Zusammenhang zwischen dieser Aussage und den Inhalten
vom Link. Es geht mir um Arrays allgemein und die werden darin nicht
einmal erwähnt

Strings als Array werden behandelt. Alternativ dieser Link:
http://openbook.rheinwerk-verlag.de/c_von_a_bis_z/027_c_sicheres_programmieren_001.htm

Und schon heute gibt es genug Technik um Fehlern seitens des 
Programmierer auszumerzen. Als Beispiel sei hier mal das NX-Bit genannt. 
Es verhindert das ein Prozess ausführbare Daten in den hinter sich 
liegenden Speicherbereich schreibt der für Nutzdaten reserviert ist.

Und generell, man entwickelt ja nicht eine Software und "schmeißt Sie 
dann mal auf den Markt", sondern testet vorher ausgiebig. Und schon da 
sollte auf entsprechende Sachen wie Pufferüberläufe, fehlerhafte 
Eingaben getestet werden.

Sollte da doch ein Fehler durchrutschen, kommt ins fertige Produkt und 
wird von jemand drittes entdeckt und missbraucht, kann man nur sagen:
Belastend für den Programmierer. So schnell wie's geht ausbessern und 
weiterleben.

Je sicherer das Zielsystem werden muss, desto länger und intensiver die 
Tests.

> Christopher C. schrieb:
> Stichwort "unsafe block" in C# oder Rust.
Wir reden hier von C und du konterst plötzlich mit C# und irgendeiner 
anderen Programmiersprache?
Wenn du das anders meintest, wärs auch schön wenn du ein paar Worte dazu 
verlierst statt einfach nur 2 Namen in den Raum zu werfen.

von Yalu X. (yalu) (Moderator)


Lesenswert?

@W.S.:

Ich bin verwundert, dass ausgerechnet ein Pascal-Fan wie du hier die
Verwendung von Goto so vehement propagiert, dazu noch in einem
Anwendungsfall, bei dem man problemlos auch mit strukturierten
Sprachelementen zu Ziel kommt.

Was soll denn der Herr Wirth von dir denken, wenn er deine Ausführungen
hier liest? ;-)

Mit der Einführung der strukturierten Programmierung wurde Goto zunächst
komplett verteufelt. Irgendwann hat man eingesehen, dass bei manchen
Dingen – wie bspw. bei der Fehlerbehandlung mit vielen Prüfbedingungen –
der Einsatz von Goto die Verschachtelungstiefe von If-Anweisungen
reduzieren und somit zur Übersichtlichkeit beitragen kann. Dazu werden
aber nur Vorwärtssprünge benötigt. Rückwärtssprünge mit Goto gelten
nach wie vor als böse¹.

Und jetzt kommst du, und empfiehlst, Goto gerade auch (oder sogar
ausschließlich?) für Rückwärtssprünge zu verwenden. Dir ist schon klar,
dass du mit dieser Idee allein auf weiter Flur stehst?

Nur so aus Interesse:

Wie würdest du eine Schleife schreiben, die ihre Abbruchbedingung in der
Mitte hat? Also bspw. so etwas:

1
  for(;;) {
2
    // mehrere Zeilen Code
3
4
    if(bedingung)
5
      break;
6
7
    // mehrere Zeilen Code
8
  }

Wann man das, was du bisher geschrieben hast, konsequent weiterführt,
müsste diese Schleife bei dir so aussehen (da es in selbstgebastelten
Goto-Schleifen ja kein Break gibt):

1
  loop1:
2
    // mehrere Zeilen Code
3
4
    if(bedingung)
5
      goto end1;
6
7
    // mehrere Zeilen Code
8
  goto loop1;
9
10
  end1:
11
  ...

Damit haben wir zwei überkreuzende Goto-Sprünge, also genau das, was
gemeinhin als Spaghetticode bezeichnet wird. Spätestens, wenn zwei
Schleifen dieses Typs ineinandergeschachtelt werden, ist das Chaos
perfekt :)

—————————————
¹) Übrigens hat auch MISRA genau diese Entwicklung durchgemacht: Früher
   waren Gotos generell verboten, heute gilt das strikte Verbot nur noch
   für Rückwärtssprünge.

: Bearbeitet durch Moderator
von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Ich habe nicht den Eindruck, daß es den Diskutanten in diesem Thread 
bislang sonderlich auf sachliche Argumente angekommen wäre. Das ist bei 
Programmiersprachenflamewars auch unnötig, denn da hat ja prinzipbedingt 
jeder recht. Und zwar ausschließlich.

von (prx) A. K. (prx)


Lesenswert?

@Rufus: Da kam schon Information rüber. Dieser Ansatz war mir unbekannt:

Yalu X. schrieb:
> Rolf M. schrieb:
>> https://staff.aist.go.jp/y.oiwa/FailSafeC/index-en.html
>
> Interessantes Projekt, werde ich mir mal etwas genauer anschauen.

von Rolf M. (rmagnus)


Lesenswert?

Christopher C. schrieb:
> Ich verstehe bis heute nicht wie man sicherheitskritische Software wie
> OpenSSL heutzutage in C schreiben kann.

Na in welcher Sprache denn sonst? C-Code kann man praktisch in allem 
anderen relativ einfach einbinden, egal ob Java, .net, Python, u.s.w. in 
allen Versionen. Welche andere Sprache bietet das so?
Ich glaube auch nicht, dass man eine bessere Fehlerfreiheit bekommt, 
wenn man für ein Dutzend Sprachen ein Dutzend separate 
SSL-Implementationen schreibt, die dann alle separat gepflegt werden 
müssen.

W.S. schrieb:
> Nochmal zum Mitschreiben: Es sind Schlüsselwörter, die zum bedingten
> Ausführen von irgendwas in der Sprache benötigt werden. So herum.

Nö. Wenn jemand mir sagt, dass er for nutzen möchte, ist das erste, was 
mir in den Sinn kommt nicht: "Der will etwas bedingt ausführen", sondern 
"der will etwas in einer Schleife ausführen".

> Versuche doch mal, dir ein if vorzustellen ohne eine Bedingung ("Da
> man diese Wiederholung MEIST an eine Bedingung knüpfen möchte..").

Im Gegensatz zu dir habe ich nicht von if gesprochen, sondern nur von 
for und while. Das sind Schleifenkonstrukte.

W.S. schrieb:
> ◔͜͡◔ ~. schrieb:
>> Und ich empfinde C als einfach.
>
> Was du empfindest, ist deine Gewöhnungssache. Tatsächlich ist C
> unübersichtlich.

So kann man sich die Welt auch einfach machen: Die Meinung anderer als 
persönliches Gefühl und die eigene einfach als Tatsache hinstellen.

> Warum? Weil in C extrem an menschlich lesbaren
> Schlüsselwörtern gespart wurde und stattdessen mit sonstigen Satzzeichen
> in unterschiedlichster Kombination gearbeitet wird.
> Beispiel gefällig?   *  *A */ X*A X**A A*
> Andere Programmiersprachen sind da wesentlich übersichtlicher, da von
> hause aus besser lesbar.

Und doch hat ein Großteil der modernen Sprachen viele dieser 
Syntaxelemente übernommen.

> Sowas wie begin und end versteht selbst ein totaler Laie auf Anhieb.

Programmieren besteht nicht nur aus dem Verstehen von ein paar 
Schlüsselwörtern. Der wesentlich schwierigere Teil ist bei allen 
Sprachen erforderlich. Daher sehe ich es nicht als besonderen Vorteil 
an, wenn ein totaler Laie ein paar mehr Syntaxelemente versteht.

>> Unlogisch: Inwiefern ist die Sprache unlogisch? Logik wird doch durch
>> den Programmierer entwickelt.
>
> Nö. Manche Sprachen sind tatsächlich logisch aufgebaut (wie Pascal oder
> Algol) und C ist eben nicht logisch aufgebaut, sondern diktatorisch.
> So nach dem Motto "hier wird das eben so gemacht, basta!"

Was ist das denn für ein Quatsch? Das gilt doch für alle Sprachen. Sie 
haben Regeln, an die man sich zu halten hat. Diktatorisch ist das immer.

> Beispiel:
> warum wurde das Gleichheitszeichen als Zuordnungsoperator mißbraucht, wo
> doch seit Erfindung der Mathematik selbiges als Gleichheitszeichen
> bereits vergeben ist und an allen Ecken bei C zusammengesetzte Zeichen
> üblch sind?

Da hast du wohl "unlogisch" mit "unintuitiv" verwechselt. Letzteres ist 
C an eigigen Stellen durchaus.

> Fehlentscheidung! Und die zieht weiteren Mumpitz nach sich,
> wie z.B. A==B

Wer hat denn festgelegt, dass man in der Programmierung Symbole 
ausschließlich im mathematischen Sinne nutzen darf?
Hast du mal eine Sprache parat, bei der das Gleichheitszeichen nicht 
"mißbraucht" wird? In Pascal z.B. wird es für den Vergleich eingesetzt, 
was genauso wenig dem mathematischen Sinn entspricht wie eine Zuweisung.

> Oder warum  muß der Ausdruck nach if denn in eine Klammer? Es gibt doch
> gar nichts zu klammern!
> bei einem Term  (A+B)*C ist klar, daß hier Klammern sein müssen, sonst
> ginge die Rechnung falsch. Aber wozu bei einem if ? Bloß, um sowas wie
> ein then zu vermeiden?

Was ist daran unlogisch? Umgekehrt könnte man auch fragen, warum man in 
Pascal extra ein Schlüsselwort then braucht. Bloß, um sowas wie Klammern 
zu vermeiden? Wie kommst du auf die Idee, ein then in einer if-Anweisung 
sei der gottgegebene Weg, von dem niemals je abgewichen werden darf?

> Oder wozu bei
> if (CharAvailable()) c = GetChar();
> die leeren Klammern, wo doch von vornherein feststeht, daß die
> betreffenden Funktionen gar keine Argumente benötigen?

Die Klammern mit den Argumenten dazwischen nach dem Identifier zeigen 
unmissverständlich, dass die Funktion aufgerufen werden soll. Wenn man 
keine Argumente zu übergeben hat, steht zwischen den Klammern eben 
nichts. Finde ich völlig logisch und auf jeden Fall besser, als wenn da 
einfach nur ein Name stünde, ohne irgendetwas, das zeigt, was denn mit 
damit überhaupt zu tun ist.

> Die Sprache macht es den Programmierern schwer, da sie keinerlei
> Sauberkeit kennt. Da wird lustig zwischen Typdefinitionen,
> Variablendeklarationen und Code gewuselt, ohne selbige sauber zu
> trennen, selbst Konstantendefinitionen lassen sich nur per Präprozessor
> - also außerhalb der eigentlichen Programmiersprache erledigen.

Ja, das fehlt tatsächlich.

> Den Treppenwitz mit sowas wie "uint32_t" und Konsorten, die erstens
> unleserlich sind und zweitens überhaupt nicht im Compiler verankert
> sind, sondern per Headerdatei auf das alte schlichte unsigned long int
> zurückgeführt werden, bevor der eigentliche Compiler sie zu fressen
> kriegt, kenne wir ja zur Genüge.

Was ist an uint32_t unleserlich? Und warum muss das unbedingt ein 
eigenes Schlüsselwort bekommen? Welchen Vorteil hätte das, außer dass 
älterer Code, der selbst einen solchen Namen definiert, inkompatibel 
dazu wird? So kann man dieses zusätzliche Feature über einen Header 
einbinden, wenn man es braucht und weglassen, wenn nicht. Welchen 
Nachteil hat es denn?

von W.S. (Gast)


Lesenswert?

Yalu X. schrieb:
> Ich bin verwundert, dass ausgerechnet ein Pascal-Fan wie du

Yalu! Du solltest hier nicht so tun, als wärest du so ein grüner Hase 
wie du es gerade tust.

Abgesehen davon bin ich überhaupt kein Fan. Weder von Pascal, noch von C 
noch von sonstwas. Ich habe allerdings eine Meinung zu all diesem 
Kruscht und benutze selbigen je nachdem, was tatsächlich Sinn macht.

Allerdings habe ich den inneren Anspruch auf sauberen und sozusagen 
"biederen" Code (egal in welcher Programmiersprache). Dazu gehört, daß 
man eben keine grandiosen Husarenstücke schreibt, auf schwer 
nachvollziehbare Konstrukte verzichtet und auf den vigilanten Ge- oder 
besser Mißbrauch von Sprachelementen verzichtet.

Wer if und else hinschreiben kann, braucht keinen Fragezeichenoperator.
Den Kommaoperator braucht man auch bloß nicht.
Entartete Konstrukte a la for(;;) braucht auch keiner.
Selbst break ist in fast allen Fällen (außer switch/case) herzlich 
überflüssig.
Dafür ist Klammerung in Ausdrücken fast immer ein Gewinn an Lesbarkeit, 
weil es eigentlich eine Zumutung ist, Vorrangregeln zu pauken.

Eigentlich weißt du das alles selbst. Also tu nicht so!

Und was dein Einwand wegen einer Abbruchbedingung inmitten einer 
Schleife betrifft: Jede Schleife würde sich so umstellen lassen, daß man 
genau dieses nicht braucht - es sei denn, man hat ein Problem, das 
dediziert nach einem goto verlangt. Ist aber eher selten.

Nochwas: Diese hirnrissige Absolutfurcht vor dem unheiligen Goto stammt 
aus der Zeit, wo jeder µC-Bursche zu allerest BASIC konnte und deshalb 
mit goto wesentlich geübter war als mit strukturiertem Programmieren. 
Die Zeit ist aber vorbei und all die obsolete Polemik aus jener Zeit 
ebenso.

Und nochwas, nicht an dich selbst:
Mir ist es eigentlich auch zu doof, auf Einwürfe wie "Was ist an 
uint32_t unleserlich?" näher einzugehen. Sowas IST unleserlich, 
genauso wie for(;;) - sonst hätte der TO hier nicht nachgefragt. 
Abgesehen davon ist uint32_t herzlich überflüssig, ein dword oder 
unsigned long int hätte es auch getan. Vielleicht sollte man Leuten, die 
sowas fragen, mal 'cardinal' vor die Nase setzen. Also, was ist denn 
unleserlich an cardinal, he?

W.S.

von W.S. (Gast)


Lesenswert?

Noch ein Nachtrag:

siehe
"Beitrag "Aus einer while Schleife springen";

Da kann man mal sehr schön sehen, wie sich Leute in sich selbst 
verstricken, wenn sie mit sowas wie while(1) herumhantieren, ohne 
wirklich irgend einen Durchblick zu haben.

W.S.

von Christopher C. (trihexagon)


Lesenswert?

Rolf M. schrieb:
> Christopher C. schrieb:
>> Ich verstehe bis heute nicht wie man sicherheitskritische Software wie
>> OpenSSL heutzutage in C schreiben kann.
>
> Na in welcher Sprache denn sonst? C-Code kann man praktisch in allem
> anderen relativ einfach einbinden, egal ob Java, .net, Python, u.s.w. in
> allen Versionen. Welche andere Sprache bietet das so?
> Ich glaube auch nicht, dass man eine bessere Fehlerfreiheit bekommt,
> wenn man für ein Dutzend Sprachen ein Dutzend separate
> SSL-Implementationen schreibt, die dann alle separat gepflegt werden
> müssen.

C++, Go und Rust können C-ABI kompatible Funktionen erstellen, die 
lassen sich dann von allerhand anderen Sprachen benutzen. Das ist 
heutzutage kein Argument mehr. Gut damals, gabs nur C++, aber das wäre 
schon ein riesiger Fortschritt zu C (Typsicherheit, Arrays mit Bounding 
checks...).

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

W.S. schrieb:
> Wer if und else hinschreiben kann, braucht keinen Fragezeichenoperator.

Der Fragezeichenoperator ist schon sinnvoll, weil er einiges an 
redundanter Schreiberei einsparen helfen kann.


Willkürliches dahingetippseltes Beispiel:
1
pstruct->myvaluearray[index] = index % 2 ? function_1(index) : function_2(index);

Ohne Fragezeichenoperator sähe das so aus:
1
if (index % 2)
2
  pstruct->myvaluearray[index] = function_1(index);
3
else
4
  pstruct->myvaluearray[index] = function_2(index);

Da steht also zweimal das gleiche.

Man muss sich vor Augen führen: C ist keine Programmiersprache, die 
dafür da ist, das Programmieren zu erlernen. C ist eine 
Programmiersprache, die dafür da ist, Ziele zu erreichen. Und mit ihren 
Freiheiten auch viel Verantwortung seitens des Nutzers mit sich bringt.

von Rolf M. (rmagnus)


Lesenswert?

W.S. schrieb:
> Und nochwas, nicht an dich selbst:
> Mir ist es eigentlich auch zu doof, auf Einwürfe wie "Was ist an
> uint32_t unleserlich?" näher einzugehen.

Hätte ich auch nicht anders erwartet. Wie oben schon geschrieben, 
erklärst du einfach deine Meinung zur unumstößlichen Tatsache, in dem 
Irrglaube, dass damit eine Begründung überflüssig wird.

> Abgesehen davon ist uint32_t herzlich überflüssig, ein dword oder
> unsigned long int hätte es auch getan.

Du hast offenbar nicht verstanden, wozu die fixed-width-Integers 
überhaupt eingeführt wurden. unsigned long int ist auf manchen 
Plattformen 64 Bit breit, und "dword" ist eine prozessorspezifische 
Bezeichnung.
Und wie "dword" oder "unsigned long int" leserlicher für einen 
32-Bit-Typ sein soll als eine Bezeichnung in der die Zahl 32 auch 
tatsächlich enthalten ist, wird wohl dein Geheimnis bleiben.

W.S. schrieb:
> Noch ein Nachtrag:
>
> siehe
> "Beitrag "Aus einer while Schleife springen"
>
> Da kann man mal sehr schön sehen, wie sich Leute in sich selbst
> verstricken, wenn sie mit sowas wie while(1) herumhantieren, ohne
> wirklich irgend einen Durchblick zu haben.

Wie überraschend, dass jemand, der keinen Durchblick hat, sein Problem 
nicht versteht. Und was hat das mit while (1) zu tun? Inwiefern wäre das 
mit deinem goto-Konstrukt anders gewesen?

von Christopher C. (trihexagon)


Lesenswert?

◔͜͡◔ ~. schrieb:
>> Christopher C. schrieb:
>> Inwiefern wurde C seit Ansi-C (1989) weiterentwickelt? Man hat ein paar
>> nette und nützliche Dinge hinzugefügt, aber das wars schon. Kein
>> Vergleich zu anderen Sprachen oder gar zu Windows.
> C11 ersetzt C99.
> Inwiefern die Änderungen einen Fortschritt darstellen... Man mag die
> Frage mal rumdrehen: Braucht es einen Fortschritt? Oder gibt es derzeit
> keinen Verbesserungsbedarf für C? Ich glaube eher nicht.

"Braucht es Fortschritt?". Nun, du kannst gerne wieder ein Leben in 
einer Höhle führen, ohne fließendes Wasser und ein warmes Bett. Nein mal 
im Ernst, was soll so eine Frage in der Informationstechnik? C ist 
inzwischen 40 Jahre alt, da gibt es so einiges was man heutzutage anders 
macht. Mir ist keine Sprache bekannt die in den letzten 20 Jahren 
erfunden wurde und keine Typsicherheit bietet. Genauso sieht es aus mit 
Templates/Generics aus. etc. etc.

Aha und was macht C11 grundsätzlich anders als C99 oder C89? Das Gremium 
macht bewusst keine großen Änderungen. Nun zu behaupten C11 sei eine 
"Weiterentwicklung" von C99 ist eher ein Witz.

◔͜͡◔ ~. schrieb:
>> Christopher C. schrieb:
>> Stichwort "unsafe block" in C# oder Rust.
> Wir reden hier von C und du konterst plötzlich mit C# und irgendeiner
> anderen Programmiersprache?
> Wenn du das anders meintest, wärs auch schön wenn du ein paar Worte dazu
> verlierst statt einfach nur 2 Namen in den Raum zu werfen.

Also bitte, was soll eigentlich dieser Tonfall? Du musst meine Aussage 
schon im richtigen Kontext interpretieren und das darüber liegende Zitat 
miteinbeziehen.

Schau mal hier:
Christopher C. schrieb:
> A. K. schrieb:
>>> Vielleicht gibt es Szenarien in denen es sogar gewollt ist, in
>>> einem Speicherbereich zu schreiben der nicht der eigene ist?
>>
>> Eine auf Sicherheit bedachte Sprache wird das als Ausnahmefall sehen und
>> dafür spezielle Mechanismen bereitstellen. Der Regelfall sind dann
>> abgesicherte Zugriffe. Denn im Regelfall wird so etwas eben nicht
>> benötigt.
>
> Stichwort "unsafe block" in C# oder Rust.

Darüberhinaus ist es so schwer "rust unsafe block" zu googeln, wenn man 
sowieso vorm PC sitzt?

https://doc.rust-lang.org/book/unsafe.html

Um es zusammenzufassen, geht es um einen Scope, in dem man all die 
Schweinerein, wie in einen fremden Addressraum zu schreiben etc., 
erlaubt sind. Ansonsten ist sowas untersagt und endet mit einer 
Fehlermeldung des Kompilers.

von Jobst Q. (joquis)


Lesenswert?

W.S. schrieb:
> Was du empfindest, ist deine Gewöhnungssache. Tatsächlich ist C
> unübersichtlich. Warum? Weil in C extrem an menschlich lesbaren
> Schlüsselwörtern gespart wurde und stattdessen mit sonstigen Satzzeichen
> in unterschiedlichster Kombination gearbeitet wird.
> Beispiel gefällig?   *  *A */ X*A X**A A*
> Andere Programmiersprachen sind da wesentlich übersichtlicher, da von
> hause aus besser lesbar. Sowas wie begin und end versteht selbst ein
> totaler Laie auf Anhieb.

Genau deshalb finde ich C gegenüber Pascal wesentlich übersichtlicher. 
Weil nicht soviel Buchstabenballast das Wesentliche überdeckt. 
Buchstaben sind in C bis auf wenige Ausnahmen (if, while, for..)für 
Typen und Namen vorgesehen, strukturiert wird mit anderen Zeichen. Diese 
deutlich sichtbare Trennung zwischen Struktur und Inhalt erleichtert mir 
das Lesen wesentlich.


Ein Quelltext ist nicht für totale Laien gedacht, sondern für 
Programmierer und Compiler. Dass ein '{' für den Beginn eines Blocks 
steht und '}' für das Ende, ist ja nun wirklich nicht schwer zu lernen.

Wenn es dir mit vielen 'begin' und 'end' lieber ist, brauchst du nur

#define begin {
#define end }

an den Anfang setzen und der C-Compiler versteht auch deine 
Lieblingsschreibweise. C ist eben nicht diktatorisch, sondern erlaubt 
mehr Freiheiten als jede andere Sprache.

> Oder warum  muß der Ausdruck nach if denn in eine Klammer? Es gibt doch
> gar nichts zu klammern!
> bei einem Term  (A+B)*C ist klar, daß hier Klammern sein müssen, sonst
> ginge die Rechnung falsch. Aber wozu bei einem if ? Bloß, um sowas wie
> ein then zu vermeiden?

'()' sind 2 Anschläge weniger als 'then' und besser als Strukturierung 
erkennbar.

Aber auch für dieses Problem von dir gibt es eine Lösung:

#define IF if(
#define THEN )

von vorticon (Gast)


Lesenswert?

Ich finde es gut, dass ihr Ueberzeugungen habt! Da sag noch einer, die 
Jugend sei unpolitisch.

Aber mal was inhaltliches: Klar ist C ein Dinosaurier, wenn man es heute 
neu erfinden wuerde, saehe das ganz anders aus. Aber dass es nach wie 
vor so verbreitet ist, ist - glaube ich - nicht hauptsaechlich die 
Faulheit nichts neues lernen zu wollen. Es ist einfach von Vorteil, Code 
zu haben, der auf x dutzend verschiedenen Plattformen kompilierbar ist, 
und es ist von Vorteil, eine Sprache zu benutzen, deren Eigenschaften 
(einschliesslich deren Schwaechen) bekannt sind.

Dennoch muss man festhalten: effizienter Code muss nicht in C 
geschrieben sein, er muss noch nicht mal kompilierbar sein. Ich 
programmiere mittlerweile fast nur in Matlab - und die meisten Sachen, 
die ich so programmiere, waeren in C nicht nennenswert schneller! 
(Abgesehen davon braeuchte man in C ohne Uebertreibung fuer vieles 
100-1000x so viele Codezeilen).

Das heisst, alles hat seinen Platz, manches aber hat seinen Platz im 
Kindergarten. Wenn while(1) praktisch ist, dann ist das doch prima. Wenn 
du das entartet nennst, dann bist du eben der Sklave von C99. Ich mach 
mir lieber Programmierkonstrukte zunutze, wie es mir gerade praktisch 
scheint.

von W.S. (Gast)


Lesenswert?

Rufus Τ. F. schrieb:
> Der Fragezeichenoperator ist schon sinnvoll, weil er einiges an
> redundanter Schreiberei einsparen helfen kann.

Ist dir DAS etwa wichtiger als der Rest der Welt?

Mir nicht.

Viel wichtiger ist Lesbarkeit - insbesondere dann, wenn man nach jahren 
an seinen eigenen Code nochmal ran muß oder wenn man Zeugs von anderen 
übernehmen oder korrekturlesen muß.

Tipparbeit einsparen zu wollen, halte ich für das Verkehrteste auf 
dieser Welt. Aber genau dieses blöde Argument hört man von überall, auch 
von Leuten, die sich in
 BlablaInitStructur.XYZ &= ~(EllenlangerBezeichner_mask);
ergehen.

Welch Irrsinn.

Oh nein, es geht hier nicht um's Ergonomische, sondern um ganz andere 
Dinge aus der nichttechnischen Welt. Aber dieses Thema hatte wir schon 
x-mal.

Frag dich also lieber mal, warum hier der TO seine Frage überhaupt 
gestellt hat.

W.S.

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

W.S. schrieb:
> Viel wichtiger ist Lesbarkeit - insbesondere dann, wenn man nach jahren
> an seinen eigenen Code nochmal ran muß oder wenn man Zeugs von anderen
> übernehmen oder korrekturlesen muß.

C-Code ist lesbar. Wenn man damit arbeitet.

Ich habe keine Probleme damit, 20 Jahre alten Code von mir zu lesen oder 
zu überarbeiten. Damit verdiene ich mir mein Brot.

Nochmal: C ist keine Sprache, die dafür gedacht ist, 
Programmieranfängern das Programmieren nahezubringen, oder Leuten beim 
Vermeiden von Fehlern zu helfen. Wer so etwas braucht, soll etwas 
anderes nehmen. Vielleicht ist auch nicht jeder gleichermaßen dafür 
geeignet, als Programmierer/Softwareentwickler o.ä. zu arbeiten?

C ist ein anspruchsvolles Werkzeug, das Übung und Erfahrung erfordert, 
um es beherrschen zu können.

W.S. schrieb:
> Tipparbeit einsparen zu wollen, halte ich für das Verkehrteste auf
> dieser Welt.

Im von mir gebrachten Beispiel wird fehlerträchtige Redundanz 
eingespart.

Soll nämlich der Code irgendwann überarbeitet werden, müsste dringend 
darauf geachtet werden, die beiden Zuweisungszeilen gleichermaßen zu 
bearbeiten. Geschieht das nicht, kann das ... interessante Effekte 
haben.

von Stefan F. (Gast)


Lesenswert?

Im Qt Framework gibt es das "forever" Makro. Wer while() und for() für 
Endlosschleifen doof findet, kann es ja mit so einem Makro machen.

von Yalu X. (yalu) (Moderator)


Lesenswert?

W.S. schrieb:
> Rufus Τ. F. schrieb:
>> Der Fragezeichenoperator ist schon sinnvoll, weil er einiges an
>> redundanter Schreiberei einsparen helfen kann.
>
> Ist dir DAS etwa wichtiger als der Rest der Welt?
>
> Mir nicht.
>
> Viel wichtiger ist Lesbarkeit

Redundanter Code ist (fast) immer schlecht, gerade auch im Hinblick 
auf
die Lesbarkeit. Nehmen wir das obige Beispiel von Rufus:

1
if (index % 2)
2
  pstruct->myvaluearray[index] = function_1(index);
3
else
4
  pstruct->myvaluearray[index] = function_2(index);

Ich brauche mindestens 3 Sekunden, um zuverlässig zu erkennen, dass in
beiden Zweigen etwas demselben Objekt (in diesem Fall einem bestimmten
Array-Element innerhalb einer Struktur) zugwiesen wird. Der Ausdruck auf
der linken Seite des Zuweisungsoperators könnte aber auch komplizierter
sein, dann dauert es entsprechend länger.

Mit dem ?:-Operator besteht dieses Problem überhaupt nicht:

1
pstruct->myvaluearray[index] = index % 2
2
                               ? function_1(index)
3
                               : function_2(index);

Hier sehe ich auf einen Blick, dass dem Objekt auf der linken Seite auf
jeden Fall etwas zugewiesen wird. Als nächstes sehe ich, dass der
zugewiesene Wert davon abhängt, ob index ungerade oder gerade ist.
Schließlich sehe ich die beiden zur Auswahl stehenden Ausdrücke.

Genau in dieser Reihenfolge und ohne die Verdoppelung einzelner
Codeabschnitte möchte ich das lesen, da mein Gehirn beim Verstehen des
Codes ebenfalls in dieser Reihenfolge arbeitet.

Es kann natürlich sein, dass andere Gehirne anders arbeiten. Aber ich
glaube, so arg groß sind die Unterschiede nicht.

W.S. schrieb:
> Und was dein Einwand wegen einer Abbruchbedingung inmitten einer
> Schleife betrifft: Jede Schleife würde sich so umstellen lassen, daß man
> genau dieses nicht braucht - es sei denn, man hat ein Problem, das
> dediziert nach einem goto verlangt. Ist aber eher selten.

Genau da haben wir das Problem mit dem redundanten Code sogar noch in
verschärfter Form. Natürlich kann man diese Schleife

1
  for(;;) {
2
    // Codeabschnitt A
3
4
    if(bedingung)
5
      break;
6
7
    // Codeabschnitt B
8
  }

so umstellen, dass die Abbruchbedingung am Anfang der Schleife steht:

1
  // Codeabschnitt A
2
3
  while(!bedingung) {
4
    // Code-Abschnitt B
5
6
    // Codeabschnitt A
7
  }

Jetzt steht aber der Codeabschnitt A zweimal da. Jemand, der das
Programm liest, wird – wenn überhaupt – erst nach längerem Hinsehen
erkennen, dass da ein Stück Code vor der Schleife mit einem Teil des
Codes in der Schleife übereinstimmt. Da er ja nicht einmal im Voraus
weiß, ob es überhaupt gleichen Code gibt und welche Code-Zeilen er dazu
vergleichen muss, bedarf es extrem guter Mustererkennungsfähigkeiten des
Gehirns, die leider nicht jeder hat.

Hat er schließlich nach langem Hinstarren erkannt, dass es sich dabei
tatsächlich um eine umgestellte Schleife handelt, wird er jubeln, sich
aber gleichzeitig fragen, warum der Idiot von Programmierer das nicht
gleich so hingeschrieben hat.

Aber das ist noch nicht alles:

Jede Änderung, die innerhalb der Schleife in Codeabschnitt A gemacht
wird, muss auch in den Zeilen vor der Schleife gemacht werden. Ich habe
es schon oft erlebt, dass danach die Änderung vor der Schleife
fehlerhaft ist. Denn bei der Änderung innerhalb der Schleife ist man
noch gezwungen nachzudenken, beim Kopieren der entsprechenden Änderung
vor die Schleife wird man leichtsinnig. Oft fehlt dann einfach eine
Zeile, oder eine Zeile steht plötzlich doppelt da.

: Bearbeitet durch Moderator
von Carl D. (jcw2)


Lesenswert?

So ein ähnliches Problem wurde von Dan Saks auf der CppCon 2016 
behandelt:
“extern c: Talking to C Programmers about C++” 
https://youtu.be/D7Sd8A6_fYU
Geht zwar 1,5h, aber die lohnen sich.

Sein Fazit (in meiner Zusammenfassung):
Verbohrte kann man mit Argumenten nicht überzeugen.

von mc.net at its best (Gast)


Lesenswert?

Frage: for(;;) bedeutung
Antwort: Endlosschleife
mc.net: 110 Antworten

Also manchmal muss man sich hier wirklich an den Kopf greifen.

von Josef G. (bome) Benutzerseite


Lesenswert?

Da ich mir nicht vorwerfen lassen will, ich würde den Thread kapern:
Beitrag "Re: Gibt es eine Programmiersprache mit diesem Schleifentyp?"

von Yalu X. (yalu) (Moderator)


Lesenswert?

mc.net at its best schrieb:
> Frage: for(;;) bedeutung
> Antwort: Endlosschleife
> mc.net: 110 Antworten

Das liegt u.a. daran, dass deine Antwort "Endlosschleife", so knackig
kurz und prägnant sie auch sein mag, nur einen winzigen Bruchteil der
gesamten Wahrheit ans Licht bringt:

Eine Schleife mit for(;;) muss mitnichten endlos laufen, denn sie darf
selbstverständlich mit einer Break-, Goto- oder Return-Anweisung schon
deutlich vor dem Ende der Ewigkeit verlassen werden ;-)

von Zeno (Gast)


Lesenswert?

Rolf M. schrieb:
> Und doch hat ein Großteil der modernen Sprachen viele dieser
> Syntaxelemente übernommen.

Da diese i.d.R alle C-lastig sind.

Zeno

von Zeno (Gast)


Lesenswert?

Rolf M. schrieb:
> Hast du mal eine Sprache parat, bei der das Gleichheitszeichen nicht
> "mißbraucht" wird? In Pascal z.B. wird es für den Vergleich eingesetzt,
> was genauso wenig dem mathematischen Sinn entspricht wie eine Zuweisung.

Uii! Das ist jetzt aber völlig daneben. Ein Gleichheitszeichen bedeutet 
im mathematischen Sinn, das auf beiden Seiten von selbigen das Gleiche 
steht. Insofern macht Pascal es richtig, denn es prüft beim Vergleich ob 
auf beiden Seiten das Gleiche steht.

Über den Zuweisungsoperator (:=) bei Pascal läßt sich sicherlich auch 
vortrefflich streiten, das ist halt ne Sache die man einfach lernen muß.

In C muß ich da aber immer umdenken und mir passiert es häufig, daß ich 
schreibe
1
 if (xy=2){....
. Das Schlimme dabei der Compiler meckert nicht und läßt das durchgehen. 
Klar der Code funktioniert dann nicht wie gewünscht und man sucht sich 
einen Wolf.

Übrigens am besten finde ich den Zuweisungsoperator von HP-Basic. Dort 
sieht das so aus :
1
 a->2
. Das ist aber Ansichtskarte und das mag auch jeder anders sehen.
Und bevor jetzt wieder unendliche Diskussionen beginnen, das ist halt 
eine Möglichkeit wie man es machen kann.


Zeno

von Zeno (Gast)


Lesenswert?

Rufus Τ. F. schrieb:
> Ohne Fragezeichenoperator sähe das so aus:
> if (index % 2)
>   pstruct->myvaluearray[index] = function_1(index);
> else
>   pstruct->myvaluearray[index] = function_2(index);
>
> Da steht also zweimal das gleiche.

Nö da steht nicht 2x das Gleiche! Das was rechts vom Gleichheitszeichen 
steht ist schon unterschiedlich.
Im übrigen empfinde ich diese Darstellungsweise übersichtlicher als den 
Fragezeichenkrampf, der auch wieder so eine Erfindung ist, die man 
pauken muß. Ok ist aber auch wieder meine persönliche Meinung.


Zeno

Ach ja: Diese -> Schreibweise ist auch wieder so ein C++ Krampf der sich 
erst mal einem erschließen muß. Bei C# nimmt man übrigens wieder einen . 
für so was, wie in anderen Programmiersprachen auch.

von Zeno (Gast)


Lesenswert?

Yalu X. schrieb:
> Hier sehe ich auf einen Blick

Du bist da Hellseher. Ich sehe da nichts auf einen Blick. DA muß ich 
schon mal das Handbuch zur Hand und nachschauen was das ? da bedeuten 
soll, um dann festzustellen daß es nichts anderes als if .. else ist.
Sorry aber da ist mir die klassische Schreibweise schon lieber.

Zeno

von Carl D. (jcw2)


Lesenswert?

Zeno:
> . Das Schlimme dabei der Compiler meckert nicht und läßt das durchgehen.
> Klar der Code funktioniert dann nicht wie gewünscht und man sucht sich
> einen Wolf.

Dann besorg dir einen Compiler, der was taugt. Der von mir benutzte ist 
kostenlos zu bekommen und hat kein Problem damit Anfängerfehler zu 
finden.

von Roland F. (rhf)


Lesenswert?

Hallo,
> Übrigens am besten finde ich den Zuweisungsoperator von HP-Basic. Dort
> sieht das so aus :
>
>     a->2
>

Für mich ist das unlogisch b.z.w. unintuitiv. Ich lese da "weise den 
Wert der Variabel a der Konstante 2 zu", gemeint ist aber sicherlich das 
Gegenteil.

rhf

von Zeno (Gast)


Lesenswert?

Carl D. schrieb:
> Dann besorg dir einen Compiler, der was taugt. Der von mir benutzte ist
> kostenlos zu bekommen und hat kein Problem damit Anfängerfehler zu
> finden.

OK! Dann schmeiß ich den GCC weg.

Zeno

von Zeno (Gast)


Lesenswert?

Roland F. schrieb:
> Für mich ist das unlogisch b.z.w. unintuitiv. Ich lese da "weise den
> Wert der Variabel a der Konstante 2 zu", gemeint ist aber sicherlich das
> Gegenteil.

War ja von mir auch als Beispiel gedacht - also prinzipiell völlig 
wertfrei. Aber ich gebe Dir recht umgekehrt wäre es sicher besser. Ich 
müßte halt noch mal meinen alten HP anschmeißen und nach schauen ob es 
wirklich so rum war, aber ich bin mir ziemlich sicher.


Zeno

von Nop (Gast)


Lesenswert?

Zeno schrieb:
> Ach ja: Diese -> Schreibweise ist auch wieder so ein C++ Krampf der sich
> erst mal einem erschließen muß. Bei C# nimmt man übrigens wieder einen .
> für so was, wie in anderen Programmiersprachen auch.

WTF?! Das sind total unterschiedliche Dinge. Den -> brauchst Du, wenn Du 
von einem Pointer auf ein struct-Element referenzieren willst. Den . 
brauchst Du, wenn Du von einem struct auf eines seiner Elemente gehen 
willst.

ptr->element ist eine Kurzschreibweise für (*ptr).element , und außerdem 
hat das mit C++ nichts zu tun, sondern das ist auch in C schon so.

von Nop (Gast)


Lesenswert?

W.S. schrieb:
> Selbst break ist in fast allen Fällen (außer switch/case) herzlich
> überflüssig.

Ich brauche das recht oft in Schleifen, genau wie continue. Zugunsten 
der Performance, was der Hauptgrund ist, wieso man nicht gleich in Java 
programmiert, sondern in C. Alternativ kann man natürlich auch 
stattdessen wie in Pascal mit zusätzlichen Flags rummachen, was 
langsamer und unübersichtlicher ist.

Aber Wirth fände das sicherlich toll. Weil sich ja auch keine seiner 
akademischen Sprachen durchgesetzt hat. Im Gegensatz zu C, was nicht von 
Akademikern zu Lehrzwecken geschaffen wurde (DAFÜR ist Pascal ja in der 
Tat gut), sondern VON Programmierern FÜR Programmierer.

von Zeno (Gast)


Lesenswert?

Nop schrieb:
> WTF?

Du meinst WPF. Das ist aber was anderes, nämlich eine spezielle Form von 
GUI.

Nop schrieb:
> sondern das ist auch in C schon so

Das mag sein. Ich hatte bisher mit diesem Konstrukt nur unter C++ zu 
tun. Ich versuche C/C++ zu vermeiden wo es nur geht. Aber dennoch bleibt 
das Konstrukt in diesem Zusammenhang Krampf und man kann es auch nicht 
schön reden.


Zeno

von Nop (Gast)


Lesenswert?

Christopher C. schrieb:
> Aha und was macht C11 grundsätzlich anders als C99 oder C89? Das Gremium
> macht bewusst keine großen Änderungen. Nun zu behaupten C11 sei eine
> "Weiterentwicklung" von C99 ist eher ein Witz.

Dinge, die gut sind, muß man auch nicht weiterentwickeln, weil sie dann 
nämlich nach einem Optimalstadium auch wieder schlechter werden. 
Fortschritt gibt es nicht unendlich. Pure Ketzerei, weiß ich, aber ich 
bin froh, daß man C nicht unnötig versaut. Wenigstens ETWAS, das nach 
wie vor gut brauchbar ist.

Wofür steht die 11 bei C++11? Für die Anzahl der Füße, die man an C++ 
angepappt hat, in der Hoffnung, einen besseren Octopus zu bekommen.

von Nop (Gast)


Lesenswert?

Zeno schrieb:
> Das mag sein. Ich hatte bisher mit diesem Konstrukt nur unter C++ zu
> tun.

Was auch nur heißt, daß Du im Grunde den Unterschied zwischen einem 
Struct und einem Pointer auf ein Struct nicht verstehst. Oder hart 
gesagt, daß Du Pointer nicht verstehst. Daß Du DANN mit C nichts 
anfangen kannst, wundert mich nicht.

von Nop (Gast)


Lesenswert?

(Nachtrag: Deswegen nutze ich C. Ich finde das super. Mit Pointern, 
Mehrfach-Dereferenzierungen und so.)

von Carl D. (jcw2)


Lesenswert?

Zeno schrieb:
> Carl D. schrieb:
>> Dann besorg dir einen Compiler, der was taugt. Der von mir benutzte ist
>> kostenlos zu bekommen und hat kein Problem damit Anfängerfehler zu
>> finden.
>
> OK! Dann schmeiß ich den GCC weg.
>
> Zeno

Oder les einfach mal was er ausgibt.

von Rolf M. (rmagnus)


Lesenswert?

Zeno schrieb:
> Rolf M. schrieb:
>> Und doch hat ein Großteil der modernen Sprachen viele dieser
>> Syntaxelemente übernommen.
>
> Da diese i.d.R alle C-lastig sind.

Java ist "C-lastig"? Was hat Java denn mit C zu tun, außer eben, dass es 
die ganzen Sonderzeichen in ihrer Bedeutung übernommen hat?

Zeno schrieb:
> Ein Gleichheitszeichen bedeutet im mathematischen Sinn, das auf beiden
> Seiten von selbigen das Gleiche steht. Insofern macht Pascal es richtig,
> denn es prüft beim Vergleich ob auf beiden Seiten das Gleiche steht.

Ebent, und das sind zwei ganz unterschiedliche Dinge. In der Mathematik 
heißt x=3, dass x hiermit den Wert 3 hat. Es wird nichts geprüft oder 
so, sondern einfach festgelegt. Wenn ich in Pascal x=3 schreibe, bekommt 
x dadurch überhaupt nicht den Wert 3, sondern kann auch einen ganz 
anderen Wert haben.

Zeno schrieb:
> Rufus Τ. F. schrieb:
>> Ohne Fragezeichenoperator sähe das so aus:
>> if (index % 2)
>>   pstruct->myvaluearray[index] = function_1(index);
>> else
>>   pstruct->myvaluearray[index] = function_2(index);
>>
>> Da steht also zweimal das gleiche.
>
> Nö da steht nicht 2x das Gleiche! Das was rechts vom Gleichheitszeichen
> steht ist schon unterschiedlich.

Richtig, das bleibt bei der ?:-Variante ja auch separat. Aber links 
steht zweimal exakt das gleiche, und genau diese Duplizierung 
verschwindet durch die Verwendung von ?:.

Zeno schrieb:
> Yalu X. schrieb:
>> Hier sehe ich auf einen Blick
>
> Du bist da Hellseher. Ich sehe da nichts auf einen Blick. DA muß ich
> schon mal das Handbuch zur Hand und nachschauen was das ? da bedeuten
> soll, um dann festzustellen daß es nichts anderes als if .. else ist.

Nein, er ist nicht Hellseher, sondern hat einfach nur die Sprache 
gelernt, die er benutzt. Der ?:-Operator ist ja nun nicht gerade 
Raketenwissenschaft. Und zu den Grndlagen beim Lernen einer Sprache 
gehört, dass man einen Überblick darüber bekommt, welche Operatoren es 
gibt und was sie machen.

> Sorry aber da ist mir die klassische Schreibweise schon lieber.

Was nun die "klassische Schreibweise" ist, darüber kann man auch 
streiten. Früher war z.B. in Shellskripten auch die Schreibweise
1
Bedingung && AktionWennWahr || AktionWennFalsch
nicht unüblich. Und die funktioniert sogar auch in C, wenn die Aktionen 
einen passenden Typ zurückgeben.

Zeno schrieb:
> Carl D. schrieb:
>> Dann besorg dir einen Compiler, der was taugt. Der von mir benutzte ist
>> kostenlos zu bekommen und hat kein Problem damit Anfängerfehler zu
>> finden.
>
> OK! Dann schmeiß ich den GCC weg.

Gerade der GCC warnt da schon immer. Man muss aber natürlich die 
Warnungen auch einschalten und lesen.

von Nop (Gast)


Lesenswert?

Zeno schrieb:
> Das Schlimme dabei der Compiler meckert nicht und läßt das durchgehen.

GCC meckert dann doch - allerdings nur, wenn man mit -Wall compiliert. 
Das sollte man aber ohnehin immer tun. Wenn Du -Wall bisher noch nicht 
kanntest, na dann guten Morgen.
1
  if (test_result = 2)
2
    do_something();

Ausgabe von GCC-ARM-NONE-EABI mit -Wall:
1
main.c: In function 'main':
2
main.c:20:5: warning: suggest parentheses around assignment used as truth value [-Wparentheses]
3
  if (test_result = 2)
4
  ^

Mit anderen Worten sagt GCC: Wenn Du das ernsthaft willst und nicht nur 
ein weiteres Gleichheitszeichen vergessen hast, dann schreib das als:
1
  if ((test_result = 2))
2
    do_something();

Dann warnt GCC nämlich nicht mehr. Das ist etwas umständlich, und zwar 
genau deswegen, weil man sich DIESE Mühe nur macht, wenn man 
ausnahmsweise wirklich zugleich zuweisen und zugleich auf ungleich 0 
prüfen will.

von Zeno (Gast)


Lesenswert?

Rolf M. schrieb:
> Gerade der GCC warnt da schon immer. Man muss aber natürlich die
> Warnungen auch einschalten und lesen.

Nop schrieb:
> GCC meckert dann doch - allerdings nur, wenn man mit -Wall compiliert.
> Das sollte man aber ohnehin immer tun. Wenn Du -Wall bisher noch nicht
> kanntest, na dann guten Morgen.

Ich kenne sehr wohl  -Wall, benutze dies und arbeite die Warnings auch 
Schritt für Schritt ab. Am Ende sind bisher alle meine Compilate ohne 
Warnings compiliert worden. Soviel mal nur zu den Warnings.
Das ist aber an dieser Stelle gar nicht das Thema. In meinem Post ging 
es darum, daß der Compiler einen klaren syntaktischen Fehler durchgehen 
läßt. In der if - Bedingung wird ein Vergleich und keine Zuweisung 
erwartet, so sieht es zumindest die Definition von if vor. Da nun mal 
das einfache = in C als Zuweisungsoperator missbraucht wird ist es ein 
klarer Fehler, wobei kein Binary erstellt werden dürfte. Fehler sollten 
auch klar als solche ausgewiesen werden. Es ist schon ein Unterschied 
zwischen nicht benutzten oder nicht initialisierten Variablen und 
syntaktischen Fehlern. Bei ersteren funktioniert das Compilat i.d.R. wie 
gewünscht bei letzterem eben nicht.

Nop schrieb:
> Mit anderen Worten sagt GCC: Wenn Du das ernsthaft willst und nicht nur
> ein weiteres Gleichheitszeichen vergessen hast, dann schreib das als:
>   if ((test_result = 2))
>     do_something();

Mal abgesehen davon, das dies mal wieder mal eine typische C Krücke ist, 
darf der Compiler das Obige nicht durch gehen lassen. Wenn Du denn Dein 
Konstrukt wirklich so hinschreiben willst, dann kann er Dich da auch mit 
einer Fehlermeldung, etwa in dieser Art "... Syntax error, blabla 
expected but "=" found...", darauf hinweisen und wenn Du wirklich die 2 
Klammern haben willst, dann wirst Du sie hinschreiben und gut. Ich 
hingegen merke sofort "=" vergessen, schreibe es hin und es ist auch 
gut.
Fazit: Eine einfache Zuweisung in der if Bedingung ist in jedem Fall 
eine Fehlermeldung wert.

Zeno

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Zeno schrieb:
> In meinem Post ging es darum, daß der Compiler einen klaren
> syntaktischen Fehler durchgehen läßt. In der if - Bedingung wird ein
> Vergleich und keine Zuweisung erwartet, so sieht es zumindest die
> Definition von if vor.

Nein. Da liegst Du falsch. if erwartet einen Ausdruck, der einen Wert 
hat. Und eine Zuweisung hat auch einen Wert.

Das ist kein syntaktischer Fehler, das ist legales C.

Allerdings ist das unüblich und wird deswegen vom gcc (und auch 
anderen Compilern) mit einer Warnung versehen.

von Rolf M. (rmagnus)


Lesenswert?

Zeno schrieb:
> Soviel mal nur zu den Warnings. Das ist aber an dieser Stelle gar nicht
> das Thema.

Naja, du hast behauptet, Compiler (und insbesondere GCC) würden da nicht 
warnen, und das ist ganz einfach falsch.

> In meinem Post ging es darum, daß der Compiler einen klaren syntaktischen
> Fehler durchgehen läßt.

Es ist kein syntaktischer Fehler.

> In der if - Bedingung wird ein Vergleich und keine Zuweisung erwartet, so
> sieht es zumindest die Definition von if vor.

Nein. In der if-Bedinung wird etwas erwartet, das einen Wert liefert. Ob 
das ein Vergleich, eine Zuweisung, ein Funktionsaufruf oder sonst was 
ist, ist egal.

> Da nun mal das einfache = in C als Zuweisungsoperator missbraucht wird
> ist es ein klarer Fehler, wobei kein Binary erstellt werden dürfte.

Nein, denn auch ein Zuweisungsoperator liefert einen Wert und kann damit 
in einer if-Abfrage verwendet werden - ganz legal. Das wird auch gerne 
mal verwendet, um z.B. den Rückgabewert einer Funktion in einer Variable 
zu speichern und gleichzeitig zu prüfen, was vor allem in Schleifen die 
oben schon erwähnte Codeduplizierung vermeidet. Sowas wie
1
while (result = fread(buf, 1, BUFSIZE, file))
2
{
3
    // arbeite mit buf
4
}
5
6
// Fehlerbehandlung
ist eine mögliche Anwendung. Ohne die Zuweisung im while müßte man 
schreiben
1
result = fread(buf, 1, BUFSIZE, file);
2
while (result)
3
{
4
    // arbeite mit buf
5
    result = fread(buf, 1, BUFSIZE, file);
6
}
7
8
// Fehlerbehandlung
und da haben wir wieder zwei identische Funktionsaufrufe, bei denen man 
immer aufpassen muss, dass man bei der Änderung des einen auch den 
anderen anpasst.

> Fazit: Eine einfache Zuweisung in der if Bedingung ist in jedem Fall
> eine Fehlermeldung wert.

Da sie kein Fehler ist, darf ein Compiler da auch keinen Fehler melden.

von Zeno (Gast)


Lesenswert?

Rolf M. schrieb:
> Java ist "C-lastig"? Was hat Java denn mit C zu tun, außer eben, dass es
> die ganzen Sonderzeichen in ihrer Bedeutung übernommen hat?

Z.B. genau deswegen. Wenn ich aus einer Programmiersprache XY einen 
Großteil der syntaktischen Elemente, Sonderzeichen etc. übernehme, dann 
ist die neue Sprache nach meinem Verständnis schon XY lastig. Das 
Übernehmen von syntaktischen Elementen ist ja per se auch erstmal nichts 
Schlimmes. Ein gewisser Wirth hat in Pascal auch Sprachelemente aus 
einer bereits vorhandenen Sprache übernommen. Als schlimm empfinde ich 
es wenn dabei grundlegende Designschwächen mit übernommen werden an 
statt sie auszumerzen.
Man muß allerdings Java zu gute halten das es vor gut 20 Jahren nicht 
mit dem Anspruch angetreten ist ein besseres C zu machen, sondern der 
Kern war eine plattformunabhängige Programmiersprache zu entwickeln. Das 
man hierbei Vieles von C übernommen hat ist wohl eher dem Bestreben 
geschuldet den Übergang von C zu Java einfacher zu gestalten. Und bevor 
hier wieder irgendwelche Diskussionen auf kommen, beweisen kann ich 
diese, meine persönliche, Meinung natürlich nicht - wozu auch.

Für mich ist und bleibt C eine Baustelle, es wurde immer wieder was dazu 
gefrickelt, was die Unzulänglichkeiten dieser Sprache nicht beseitigt 
hat. Und logisch ist die Sprache auch nicht. Solche Konstrukte wie 
while(1), for(;;) ... gehören mindestens genau so an den Pranger 
gestellt wie goto. Wenn alles so logisch wäre würden solche Fragen wie 
die des TO gar nicht gestellt werden.

Trotz aller Unzulänglichkeiten bleibt C eine mächtige Sprache mit der 
man schon einiges auf die Beine stellen kann und bei µC Programmierung 
führt, mal abgesehen von Basecom, auch kein Weg daran vorbei - leider.


Zeno

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Zeno schrieb:
> Für mich ist und bleibt C eine Baustelle, es wurde immer wieder was dazu
> gefrickelt, was die Unzulänglichkeiten dieser Sprache nicht beseitigt
> hat.

Bevor Du C "Unzulänglichkeiten" unterstellst, wäre es hilfreich, C zu 
lernen. Deine bisherigen Kommentare lassen diesbezüglich bei Dir noch 
viel Potential erkennen.

Am Stammtisch ist jeder sich selbst der beste Bundestrainer ...

von Zeno (Gast)


Lesenswert?

Rufus Τ. F. schrieb:
> Nein. Da liegst Du falsch. if erwartet einen Ausdruck, der einen Wert
> hat. Und eine Zuweisung hat auch einen Wert.

Das sehe ich schon richtig. if leitet eine Verzweigung ein und erwartet 
dazu als Bedingung einen boolschen Ausdruck. In der einschlägigen 
Literatur heiß es dazu "if(boolean_expression) {
   /* statement(s) will execute if the boolean expression is true 
*/......"
und blabla=5 ist nun mal kein boolscher Ausdruck (von NOP's Konstrukt 
mit den 2 Klammern mal abgesehen) sondern eine simple Zuweisung eines 
numerischen Wertes zu einer Variable. Und da es eben kein boolscher 
Ausdruck ist, ist es als if-Bedingung eben ein Fehler und auch als 
solcher zu behandeln. Alles andere ist wieder mal Gemurkse.

Zeno

von (prx) A. K. (prx)


Lesenswert?

Rufus Τ. F. schrieb:
> Allerdings ist das unüblich und wird deswegen vom gcc (und auch
> anderen Compilern) mit einer Warnung versehen.

Andersrum. Ein Assignment in der Bedingung ist ziemlich verbreitet. Aber 
weil vorsichtige Compiler
  while (n = f(...))
nicht so doll finden, schreiben die Leute mittlerweile
  while ((n = f(...)) != 0)

: Bearbeitet durch User
von Zeno (Gast)


Lesenswert?

Rufus Τ. F. schrieb:
> Bevor Du C "Unzulänglichkeiten" unterstellst ...

Sorry C hat viele Unzulänglichkeiten und die verschwinden nicht durch 
Lernen.

Im übrigen solltest gerade Du als Moderator mal diesen arroganten O Ton 
weglassen, dafür gibt es überhaupt keinen Grund. Im übrigen bin ich ja 
nicht der einzige der von Unzulänglichkeiten in C spricht. Lies einfach 
mal den Thread von Anfang an, da gibt es mindestens 3 Leute die die 
gleiche Meinung vertreten.

Ebensowenig behaupte ich ja das andere Programmiersprachen frei von 
Fehlern sind bzw. dort alles gut ist.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Zeno schrieb:
> Solche Konstrukte wie while(1), for(;;) ... gehören mindestens genau so
> an den Pranger gestellt wie goto.

Weil die Endlosschleife ja auch der typische Anwendungsfall in
einer Programmiersprache ist, dass man ihm unbedingt ein eigenes
syntaktisches Element spendieren muss?

Es wurde bereits festgestellt, dass es nur sehr, sehr wenige Sprachen
gibt, die für diesen Sonderfall ein eigenes Element vorhalten.  Aus
gutem Grund: man gibt sich normalerweise Mühe, die Anzahl der
reservierten Worte in einer Sprache nicht ausufern zu lassen.

Wenn dich das “for (;;)” wirklich so beim Lesen stört, kannst du ja
allemal ein
1
#define forever for (;;)

oder, nach Belieben
1
#define forever while (1)

irgendwo in ein Headerfile schreiben.

Zeno schrieb:
> if leitet eine Verzweigung ein und erwartet dazu als Bedingung einen
> boolschen Ausdruck.

Nein:
1
6.8.4.1 The if statement
2
Constraints
3
1
4
The controlling expression of an if statement shall have scalar type.

Da steht nichts von “Boolean”.

von Zeno (Gast)


Lesenswert?

Rolf M. schrieb:
> while (result = fread(buf, 1, BUFSIZE, file))
> {
>     // arbeite mit buf
> }
>
> // Fehlerbehandlung
>
> ist eine mögliche Anwendung. Ohne die Zuweisung im while müßte man
> schreiben
> result = fread(buf, 1, BUFSIZE, file);
> while (result)
> {
>     // arbeite mit buf
>     result = fread(buf, 1, BUFSIZE, file);
> }

Das kann man auch anders und nach meinem Verständnis auch besser machen. 
A.K. hat es ein paar Posts weiter unten aufgezeigt. Diese Schreibweise 
ist eindeutig und da wird kein Compiler meckern, weil es korrekt 
hingeschrieben wurde.

Zeno

von Yalu X. (yalu) (Moderator)


Lesenswert?

Zeno schrieb:
> Wenn ich aus einer Programmiersprache XY einen Großteil der
> syntaktischen Elemente, Sonderzeichen etc. übernehme, dann ist die
> neue Sprache nach meinem Verständnis schon XY lastig.

Eine Sprache besteht aber aus mehr als nur aus Syntax. Für mich ist es
zweitrangig, ob eine logische UND-Verknüpfung mit "and", ".AND.", "&"
oder "&&" geschrieben wird, entscheidend ist vielmehr, ob es diese
Operation in einer Sprache möglich ist oder nicht.

> Als schlimm empfinde ich es wenn dabei grundlegende Designschwächen
> mit übernommen werden an statt sie auszumerzen.

Nimm als Beispiel Python: Es werden im Wesentlichen die gleichen
Operatorsymbole wie in C verwendet. Der in C aus historischen Gründen
bestehende, aber häufig kritisierte Vorrang der Vergleichs- vor den
Bitoperatoren wurde in Python geändert.

> Das man hierbei Vieles von C übernommen hat ist wohl eher dem
> Bestreben geschuldet den Übergang von C zu Java einfacher zu
> gestalten.

Eben. Man muss ja das Rad nicht ständig neu erfinden. Die Aktzeptanz
neuer Sprachen steigt gewaltig, wenn die Programmierer nicht jedesmal
wieder bei Null anfangen müssen.

> Für mich ist und bleibt C eine Baustelle, es wurde immer wieder was dazu
> gefrickelt, was die Unzulänglichkeiten dieser Sprache nicht beseitigt
> hat.

Nenne mir eine Sprache, die schon eine gewisse Reife hat (also älter als
ca. 10 Jahre ist), und bei der dies nicht der Fall ist. Da dieses
Problem in ähnlicher Form auch bei natürlichen SPrachen besteht, nehme
ich an, dass das in der Natur der Sache liegt und einfach akzeptiert
werden sollte.

von (prx) A. K. (prx)


Lesenswert?

C ist syntaktisch nun einmal streckenweise etwas eigenwillig. Das ist 
nicht neu. Sich aber ausgerechnet über so triviales wir die Eleganz von 
for(;;) oder while(1) aufzuregen, wirkt auf mich reichlich absurd.

von Huh (Gast)


Lesenswert?

Zeno schrieb:
> Solche Konstrukte wie
> while(1), for(;;) ... gehören mindestens genau so an den Pranger
> gestellt wie goto.

Der eine stellt "while(1)" an den Pranger, der andere "for(;;)". Und 
"goto" ist sowieso für alle "bäh". Jetzt kommst du und willst alle drei 
Varianten nicht. Was bleibt dann noch übrig für eine Endlosschleife? 
Diesen Vorschlag, wie man es nun richtig macht, hast du vergessen!

Denk immer daran:
Meckern ohne einen besseren Vorschlag zu haben ist wenig konstruktiv!

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Jörg W. schrieb:

> Es wurde bereits festgestellt, dass es nur sehr, sehr wenige Sprachen
> gibt, die für diesen Sonderfall ein eigenes Element vorhalten.

p.s.:

https://en.wikipedia.org/wiki/Infinite_loop#Language_support

Ob das Weglassen der Bedingungen in Go (for {}) nun wirklich
übersichtlicher ist als das Weglassen des mittleren Teils in C
(for (;;) {}), halte ich schon arg für Geschmackssache.  Ein “for”
ohne Bedingung liest sich irgendwie komisch, denn in der englischen
Syntax fehlt dann was … “loop … end loop” in Ada ist eher zu
verstehen, aber halt eine völlig andere Syntax als C.  Nun ist Ada
sicher keine schlechte Programmiersprache, aber wenn man sich ihre
tatsächliche Verbreitung anschaut: irgendwas muss es sein, dass sie
nicht die allgegenwärtige Sprache in der Controllerwelt ist.

Manchmal ist halt etwas Pragmatismus der Sache durchaus förderlich.

Dass C durchaus Unzulänglichkeiten hat, wird übrigens kaum einer
bestreiten.  Diese aber nun gerade an der Syntax der Endlosschleife
festmachen zu wollen, ist einfach nur lächerlich.

: Bearbeitet durch Moderator
von Zeno (Gast)


Lesenswert?

@Jörg

Das #define macht es auch nicht besser, sondern ich schreibe es nur an 
eine andere Stelle.
Ja die meisten Programmiersprachen halten kein Konstrukt vor um eine 
Endlosschleife zu programmieren und das ist auch gut so. Es geht hierbei 
aber wohl weniger darum ein syntaktisches Element einzusparen, sondern 
eher darum, daß Endlosschleifen i.d.R. eher ungewollt sind, außer eben 
bei µC.
Gut ein Windowsprogramm ist letztendlich auch eine Endlosschleife die 
erst durch gezieltes Beenden des Programmes verlassen wird. Da setzt 
sich aber meist der Programmierer nicht hin und programmiert selbige, 
sondern das übernimmt in aller Regel die benutzte IDE.


Jörg W. schrieb:
> Zeno schrieb:
>> if leitet eine Verzweigung ein und erwartet dazu als Bedingung einen
>> boolschen Ausdruck.
>
> Nein:
> 6.8.4.1 The if statement
> Constraints
> 1
> The controlling expression of an if statement shall have scalar type.
>
> Da steht nichts von “Boolean”.

Ich habe mir das nicht aus den Fingern gezogen. Ich habe dies auch 
begründet und dazu eine Beschreibung des if Befehls aus der Literatur 
zitiert.
Dieser Kram mit dem Zuweisungsoperator funktioniert nur, weil in C alles 
was verschieden von 0 ist als true interpretiert wird (s. hier 
https://msdn.microsoft.com/en-us/library/fh88ctk1.aspx).

Zeno

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Zeno schrieb:
> Das sehe ich schon richtig. if leitet eine Verzweigung ein und erwartet
> dazu als Bedingung einen boolschen Ausdruck. In der einschlägigen
> Literatur heiß es dazu

Was für eine "einschlägige Literatur" mag das sein?

Zeno schrieb:
> Ich habe dies auch begründet und dazu eine Beschreibung des if Befehls
> aus der Literatur zitiert.

Nochmal (weil's so schön ist) aus welcher Literatur?

von Dirk B. (dirkb2)


Lesenswert?

Zeno schrieb:
> Ich habe mir das nicht aus den Fingern gezogen. Ich habe dies auch
> begründet und dazu eine Beschreibung des if Befehls aus der Literatur
> zitiert.

Die Unzulänglichkeit des Autors dies richtig zu Beschreiben und deine 
Unzulänglichkeit dies zu Verstehen, kannst du aber nicht als 
Unzulänglichkeit von C auslegen.

Für C gibt es einen gültigen Standard. Der ist Entscheidend.

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

1:
Zeno schrieb:
> Ach ja: Diese -> Schreibweise ist auch wieder so ein C++ Krampf der sich
> erst mal einem erschließen muß. Bei C# nimmt man übrigens wieder einen .
> für so was, wie in anderen Programmiersprachen auch.

2:
Zeno schrieb:
> Fazit: Eine einfache Zuweisung in der if Bedingung ist in jedem Fall
> eine Fehlermeldung wert.

An Deiner Stelle würde ich einfach die Klappe halten und still mitlesen. 
Steht Dir besser und Du kannst vielleicht noch etwas lernen. Deine 
unqualifizierten Äußerungen, die lediglich pure Unkenntnis von der 
Materie verraten, machen diesen Thread leider nicht lesbarer. Ganz im 
Gegenteil.

von Zeno (Gast)


Lesenswert?

Yalu X. schrieb:
> Nenne mir eine Sprache, die schon eine gewisse Reife hat (also älter als
> ca. 10 Jahre ist), und bei der dies nicht der Fall ist. Da dieses
> Problem in ähnlicher Form auch bei natürlichen SPrachen besteht, nehme
> ich an, dass das in der Natur der Sache liegt und einfach akzeptiert
> werden sollte.

Da gebe ich Dir schon recht. Fehlerfrei gibt es ebenso wenig wie per 
perfekt, oder anders ausgedrückt wo Licht ist ist auch Schatten. Nur man 
muß den Schatten auch benennen dürfen und da wird es hier im Forum eng, 
sobald man was gegen das allseits beliebte C sagt. Nur weil der Anteil 
an Programmen die in C oder dessen Abkömmlingen geschrieben sind, 
bedeutet dies nicht das C der Weisheit letzter Schluß. Vieles ist halt 
historisch gewachsen und man muß es halt wie Jörg sagt pragmatisch 
sehen.
Ich benutze ja C auch, aber deswegen muß ich es ja nicht gut finden.
Ich frage mich da schon warum sich C Programmierer immer sofort 
persönlich angeriffen sehen, wenn man Kritik an C übt.
Wenn man mal in anderen Programmierforen liest, dann stellt man schnell 
fest, das dies eigentlich nur bei C so ausgeprägt ist. In Foren für 
andere Programmiersprachen wird man auch nicht gleich als Depp 
hingestellt oder dumm angemacht, wenn man mal was nicht weis, eine Frage 
stellt die doch eigentlich völlig klar sein sollte, Kritik übt oder 
einfach nur eine andere Meinung vertritt.


Zeno

von (prx) A. K. (prx)


Lesenswert?

Zeno schrieb:
> Ach ja: Diese -> Schreibweise ist auch wieder so ein C++ Krampf der sich
> erst mal einem erschließen muß.

Ein C Krampf. Aber Krampf ist es, das stimmt. Der Kernfehler lag 
freilich woanders: die Dereferenzierung als Präfix- statt 
Postfix-Operator zu definieren. Der -> Operator ist nur die Konsequenz.

: Bearbeitet durch User
von Zeno (Gast)


Lesenswert?

Rufus Τ. F. schrieb:
> Nochmal (weil's so schön ist) aus welcher Literatur?

Benutze doch einfach mal Google. Da werden Dir ca. 2.920.000.000 
Ergebnisse zu if präsentiert u.a. auch Auszüge aus der Literatur, 
C-Tutoriale etc. etc.

Zeno

von Zeno (Gast)


Lesenswert?

Frank M. schrieb:
> An Deiner Stelle würde ich einfach die Klappe halten und still mitlesen.
> Steht Dir besser und Du kannst vielleicht noch etwas lernen. Deine
> unqualifizierten Äußerungen, die lediglich pure Unkenntnis von der
> Materie verraten, machen diesen Thread leider nicht lesbarer. Ganz im
> Gegenteil.

Na auf Deine Meinung haben ja sicher alle gewartet. Du hast bisher 
nichts zur Diskussion beigetragen und erdreistest Dich andere 
Forenteilnehmer dumm anzumachen.
Dein Beitrag trägt ja nun mal gar nichts zum Thema bei und in diesem 
Sinne solltest Du Dich eher zurückhalten.

Zeno

von Yalu X. (yalu) (Moderator)


Lesenswert?

Huh schrieb:
> Der eine stellt "while(1)" an den Pranger, der andere "for(;;)". Und
> "goto" ist sowieso für alle "bäh". Jetzt kommst du und willst alle drei
> Varianten nicht. Was bleibt dann noch übrig für eine Endlosschleife?
> Diesen Vorschlag, wie man es nun richtig macht, hast du vergessen!

Ich werde mal für ihn einspringen:

Die Lösung aller Endlosschleifenprobleme und damit die Quintessenz
dieses Threads heißt:

                         Endrekursion

Dazu braucht man keine spezielle Syntax, über die sich jemand aufregen
könnte, keine "entarteten" Konstrukte, kein Goto, sondern lediglich
Funktionsaufrufe, deren Syntax aber allgemein akzeptiert zu sein
scheint.

Beispiel:

1
#include <stdio.h>
2
3
void loop(void) {
4
  printf("loop\n");
5
  loop();
6
}
7
8
int main(void) {
9
  loop();
10
  return 0;
11
}

So genau macht man das und nicht anders.

Eigentlich könnte der Thread jetzt geschlossen werden. Ich tue es nur
deswegen nicht, weil die Diskussion gerade so lustig ist ;-)

von Zeno (Gast)


Lesenswert?

Dirk B. schrieb:
> Die Unzulänglichkeit des Autors dies richtig zu Beschreiben und deine
> Unzulänglichkeit dies zu Verstehen

Ach so! Alle anderen außer Dir sind blööd - so kann man es natürlich 
auch sehen.

Zeno

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

Zeno schrieb:
> Du hast bisher nichts zur Diskussion beigetragen [...]

Ich hatte zunächst unter meinen Beitrag auch noch die Begründungen 
geschrieben, warum Deine Äußerungen 1) und 2) absoluter Unsinn sind. 
Aber ich habs mir dann doch verkniffen und die Zeilen wieder gelöscht.

Dann zum Inhalt:

zu 1: Neben dem Operator "->" in C/C++ gibt es auch den Operator ".". 
Aus Deinem Beitrag wird klar, dass Du den Unterschied der Bedeutung 
nicht kennst, sonst würdest Du "->" in C++ nicht mit dem Operator "." in 
C# vergleichen.

zu 2: Eine Zuweisung in einer if-Bedingung ist in C ausdrücklich 
erlaubt. Würde der C-Compiler hier eine Fehlermeldung ausgeben, wäre das 
ein Bug - und zwar im Compiler. Allerhöchstens eine Warnung wäre 
angebracht, mehr aber auf keinen Fall.

Beide Äußerungen disqualifizieren Dich leider an der Teilnahme. Die 
Tatsache, dass Dir das Ganze überhaupt noch nichtmals peinlich ist, 
unterstützt den Eindruck, dass hier ein Blinder über Farben diskutieren 
will.

Und nun zum Vorwurf, ich würde mich nicht an der Diskussion beteiligen: 
Es gibt hier keinen Beitragszwang. Den solltest Du doch öfter auch mal 
beherzigen.

von Zeno (Gast)


Lesenswert?

Yalu X. schrieb:
> Beispiel:
>
> #include <stdio.h>
>
> void loop(void) {
>   printf("loop\n");
>   loop();
> }
>
> int main(void) {
>   loop();
>   return 0;
> }

Wieder was gelernt. Das finde ich persönlich gut, weil sehr gut lesbar 
und logisch. Auf die Idee die Endlosschleife über einen rekursiven 
Funktionsaufruf zu lösen bin ich bisher noch nicht gekommen. Das 
Konstrukt gefällt mir eigentlich so gut, daß ich es wahrscheinlich ab 
jetzt öfter nutzen werde.

Es wird hier aber genug Leute geben die wieder was zu meckern haben. 
Hättest Du das mal eher gepostet, dann hättest Du einigen Post hier die 
GRundlage entzogen.


Zeno

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Zeno schrieb:
> Alle anderen außer Dir sind blööd - so kann man es natürlich auch sehen.

Was ich oben zitiert habe, ist der Standard, der die
Programmiersprache C beschreibt.  Da steht eben nun einmal nichts
von einem „Booleschen Ausdruck“ oder dergleichen.  Wenn andere das
in der Literatur so beschreiben, kannst du nicht nur aufgrund deren
Beschreibung daherkommen und verlangen, dass ein Compiler für
irgendwas einen Fehler auszuspucken hätte.  Hat er nicht, darf er
nicht.

Wenn dir diese sprachliche Eigenheit (und andere) von C nicht
gefallen, dann nimm diese Sprache doch besser nicht, aber mach
dich nicht öffentlich lächerlich.  Es gibt Dinge in C, die viel
mehr zu kritisieren wären als das.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Zeno schrieb:

> Es wird hier aber genug Leute geben die wieder was zu meckern haben.

Beispielsweise der übergelaufene Stack deines Prozessors.

von Vlad T. (vlad_tepesch)


Lesenswert?

Zeno schrieb:
> Benutze doch einfach mal Google. Da werden Dir ca. 2.920.000.000
> Ergebnisse zu if präsentiert u.a. auch Auszüge aus der Literatur,
> C-Tutoriale etc. etc.
>
> Zeno

warum postest du nicht einfach deine Quelle?

von Jörg W. wurde hier ( Jörg W. schrieb: ) immerhin 
schon direkt aus dem C-Standard zitiert und deine Quelle widerlegt.

Zeno schrieb:
> Ich frage mich da schon warum sich C Programmierer immer sofort
> persönlich angeriffen sehen, wenn man Kritik an C übt.

Das tut hier keiner.
Jeder hier weiß, dass C seine Schwächen hat. Ein fehlendes Syntaxelement 
für Endlosschleifen ist einfach mal keins.
Und du stellst falsche Behauptungen auf, auf die du hier halt 
Widerspruch erntest.

von Yalu X. (yalu) (Moderator)


Lesenswert?

Zeno schrieb:
> Auf die Idee die Endlosschleife über einen rekursiven Funktionsaufruf
> zu lösen bin ich bisher noch nicht gekommen. Das Konstrukt gefällt mir
> eigentlich so gut, daß ich es wahrscheinlich ab jetzt öfter nutzen
> werde.

Es freut mich zwar, dass dir mein Vorschlag gefällt, aber so ganz
todernst war er eigentlich nicht gemeint.


Jörg W. schrieb:
> Zeno schrieb:
>
>> Es wird hier aber genug Leute geben die wieder was zu meckern haben.
>
> Beispielsweise der übergelaufene Stack deines Prozessors.

Das ist zumindest beim GCC kein Problem. Ab -O2 oder -Os macht der
Tail-Call-Elimination. Hier ist der entsprechende Ausschnitt aus dem
erzeugten Code für einen AVR:

1
.LC0:
2
  .string  "loop"
3
loop:
4
.L2:
5
  ldi r24,lo8(.LC0)
6
  ldi r25,hi8(.LC0)
7
  rcall puts
8
  rjmp .L2

: Bearbeitet durch Moderator
von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

Zeno schrieb:
> Wieder was gelernt. Das finde ich persönlich gut, weil sehr gut lesbar
> und logisch. Auf die Idee die Endlosschleife über einen rekursiven
> Funktionsaufruf zu lösen bin ich bisher noch nicht gekommen.

Das Posting von Yalu war pure Ironie:
1
cc loop.c -o loop && ./loop
2
loop
3
loop
4
...
5
Segmentation fault

Dass Dir der offensichtliche Stackoverflow überhaupt nicht auffällt, 
disqualifiziert Dich nochmals.

EDIT:
@Yalu: mach den Thread bitte zu. Man bekommt zunehmend Kopfschmerzen 
beim Lesen.

: Bearbeitet durch Moderator
von Vlad T. (vlad_tepesch)


Lesenswert?

Yalu X. schrieb:
> Die Lösung aller Endlosschleifenprobleme und damit die Quintessenz
> dieses Threads heißt:
>
>                          Endrekursion

^^

Yalu X. schrieb:
> sondern lediglich
> Funktionsaufrufe, deren Syntax aber allgemein akzeptiert zu sein
> scheint.

sicher? zitat von oben:

c-hater schrieb:
> Und diesem Ursprung haben wir auch solche Stilblüten, wie das von mir
> besonders beliebte Pattern "void function x(void)" zu verdanken. Nur
> C-lover glauben ernsthaft, dass sowas eine Sprache ist...

nicht, dass ich den ernst nehmen würde, da das erstens keine C-Signatur 
ist und zweitens er sich sowieso schon des öfteren, als ernstzunehmender 
Diskussionsteilnehmer disqualifiziert hat...
- aber nur so als einwand :)

Jörg W. schrieb:
> Zeno schrieb:
>
>> Es wird hier aber genug Leute geben die wieder was zu meckern haben.
>
> Beispielsweise der übergelaufene Stack deines Prozessors.

Theoretisch ließe sich das ja optimieren. Die Frage ist, darf man das, 
oder verletzt das die as-if Regel?

Edit: okay, die Antwort hat Yalu mittlerweile schon geliefert

Yalu X. schrieb:
> Das ist zumindest beim GCC kein Problem. Ab -O2 oder -Os macht der
> Tail-Call-Elimination.

: Bearbeitet durch User
von Zeno (Gast)


Lesenswert?

Frank M. schrieb:
> Beide Äußerungen disqualifizieren Dich leider an der Teilnahme. Die
> Tatsache, dass Dir das Ganze überhaupt noch nichtmals peinlich ist,
> unterstützt den Eindruck, dass hier ein Blinder über Farben diskutieren
> will.

Hättest Du mal Deine ausführliche Begründung drin gelassen, dann hätte 
ich wahrscheinlich eine andere Antwort geschrieben. Aber statt dessen 
hast Du nur den arroganten Fatzke heraushängen lassen und Du tust es 
wieder wie man dem Zitat entnehmen kann. Ich lasse mir von Dir ganz 
gewiß nicht den Mund bzw. die Teilnahme an diesem Forum verbieten.

Ich habe nie behauptet das ich mich in C / C++ von A bis Z auskenne. Ich 
habe meine Prioritäten anders gesetzt und benutze C nur für µC, weil es 
da eigentlich nichts anderes gibt. Mit C++ habe ich auch nur mal ein 
kleines Projekt gemacht und da hat mein Wissen über diese Sprache 
allemal ausgereicht.

Und auch wenn ich nicht allwissend bin, muß es schon gestattet sein, zu 
sagen das man dies und jenes nicht so toll findet. Man muß ja nicht 
einer Meinung sein und genau aus diesem Grund wird ja in Foren auch über 
solche Sachen diskutiert. Man sollte aber hierbei nicht die gute 
Kinderstube vergessen und ausfallend werden. Dinge die Dir 
offensichtlich nicht in die Wiege gelegt worden sind. Andere 
Forenteilnehmer, wie z.B Yalu, Jörg oder A.K., machen es doch vor das es 
auch anders geht. Sie bleiben sachlich und diskutieren mit Argumenten 
und nicht Diffamierungen.

Zeno

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Zeno schrieb:
> Und auch wenn ich nicht allwissend bin, muß es schon gestattet sein, zu
> sagen das man dies und jenes nicht so toll findet.

Kann man so machen, aber es ist hilfreich, wenn man sich dabei nicht 
total verrennt, weil man etwas komplett falsch verstanden hat. Und das 
ist Dir hier gelungen.

Im übrigen warte nicht nur ich darauf, daß Du belegst, wo Du Deine 
"Literatur" gefunden haben willst. Daß Dein 
"Google-es-Dir-doch-selbst"-Verweis hier nicht zielführend ist, sollte 
Dir klar sein.

von Nop (Gast)


Lesenswert?

Zeno schrieb:
> Das sehe ich schon richtig. if leitet eine Verzweigung ein und erwartet
> dazu als Bedingung einen boolschen Ausdruck.

Das mag in Pascal so sein, aber nicht in C. Aus dem einfachen Grund, 
weil C zwar seit C99 einen Datentyp Bool hat, aber im Grunde den Begriff 
des Boolean überhaupt nicht kennt. Für If-Ausdrücke ist der Ausdruck 
logisch falsch, wenn er 0 ist. Alles andere als 0 ist logisch wahr.

Dir sind vielleicht Konstrukte wie
1
while (n--) {...}

schonmal untergekommen? Geht auch mit
1
if (n) {...}

Also sich als jemand, der sichtlich nur ein, zwei oberflächliche Artikel 
über C gelesen hat, über angebliche Compilerfehler zu beschweren, ist 
schon humoresk.

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

Zeno schrieb:
> Ich lasse mir von Dir ganz
> gewiß nicht den Mund bzw. die Teilnahme an diesem Forum verbieten.

Verbieten will ich Dir gewiss nichts. Ich wollte Dir nur die 
Peinlichkeit ersparen, Dich weiter zum Affen zu machen. Manchmal ist 
stilles Mitlesen angebrachter. Wie ich bereits schrieb: Dabei kann man 
jede Menge lernen - auch ohne aktive Teilnahme.

Eine aktive Teilnahme empfiehlt sich erst dann, wenn man sich sicher 
ist, dass man auch mitreden kann. Bis dahin sollte man es eher 
unterlassen, weil damit nichts neues in die Diskussion gelangt, sondern 
im Gegenteil der Thread auf Abwege geführt wird, welche eine 
Konzentration auf das eigentliche Thema stark behindert.

Diese dann notwendigen Richtigstellungen verschmutzen einfach diesen 
Thread auf unerträgliche Weise. Aus diesem Grund hatte ich mich zunächst 
auf einen kurzen Beitrag beschränkt - was Dir dann wiederum nicht 
passte. Jetzt passiert genau das, was ich eigentlich nicht wollte: Man 
diskutiert nun nicht mehr übers Thema, sondern über diverse Beiträge. 
Blöd gelaufen.

von Rolf M. (rmagnus)


Lesenswert?

Zeno schrieb:
> Gut ein Windowsprogramm ist letztendlich auch eine Endlosschleife die
> erst durch gezieltes Beenden des Programmes verlassen wird. Da setzt
> sich aber meist der Programmierer nicht hin und programmiert selbige,
> sondern das übernimmt in aller Regel die benutzte IDE.

Aha, und wenn dir das die IDE hinschreibt, ist das besser, als wenn es 
der Präprozessor tut?

Zeno schrieb:
> Da gebe ich Dir schon recht. Fehlerfrei gibt es ebenso wenig wie per
> perfekt, oder anders ausgedrückt wo Licht ist ist auch Schatten. Nur man
> muß den Schatten auch benennen dürfen und da wird es hier im Forum eng,
> sobald man was gegen das allseits beliebte C sagt.

Es geht eher darum, dass "man" Sachen sagt, die so einfach nicht 
stimmen.

Vlad T. schrieb:
> Jörg W. schrieb:
>> Zeno schrieb:
>>
>>> Es wird hier aber genug Leute geben die wieder was zu meckern haben.
>>
>> Beispielsweise der übergelaufene Stack deines Prozessors.
>
> Theoretisch ließe sich das ja optimieren. Die Frage ist, darf man das,
> oder verletzt das die as-if Regel?

Warum sollte man das nicht dürfen? C schreibt ja nicht vor, dass bei 
einer zu großen Rekursionstiefe der Stack überzulaufen hat. Es schreibt 
nicht mal die Existenz eines Stacks vor.

von mec (Gast)


Lesenswert?

A. K. schrieb:
> So gibt es in C keine Möglichkeit, einer Funktion als Parameter ein
> Array zu übergeben. In der Funktion ist das kein Array mehr, die
> Information über die Länge ist nicht mehr vorhanden. Dass der
> Programmierer diese Länge separat übergeben und Zugriffe zu Fuss prüfen
> kann ist kein gleichwertiger Ersatz dafür.

Dafür gibt es doch struct ;)


C ist für manches die beste Sprache und für anderes schlecht.
Das selbe gilt auch für Assembler, C++, Pascal, Basic, Brainfuck, Java, 
C#...
Ok, es gibt Ausnahmen von der Regel: VisualBasic für .Net ist nirgends 
die Beste sprache ;)

von mec (Gast)


Lesenswert?

W.S. schrieb:
> Kurzum: C is nicht mehr renovierungsfähig. Man kann damit leben, in
> vielen Gebieten wie µC-Programmierung muß man das auch mangels Tools für
> andere Sprachen und C reicht eigentlich auch für recht vieles völlig
> aus, aber eine wirklich gute Programmiersprache ist C wahrlich nicht.

Du hast nicht verstanden, für was C Gemacht wurde. Überlage mal, warum C 
bei Mikrocontrollern so beliebt ist? Bei C geht es darum, die Hardware 
effiziient nutzen zu können, ohne das man die ganze Zeit irgendwelche 
Hürden aufwendig aus dem Weg räumen zu müssen. C ist die Planierraupe, 
welche den Weg für die Formel1 Rennstrecke freiräumt, wo dann z.B. die 
Teams Java, C# etc. unterwegs sind

von Zeno (Gast)


Lesenswert?

Nop schrieb:
> Für If-Ausdrücke ist der Ausdruck
> logisch falsch, wenn er 0 ist. Alles andere als 0 ist logisch wahr.

Ich meine das hatte ich schon weiter oben selbst hin geschrieben, aber 
sei's drum.
Und selbst wenn das in C so ist und zum Sprachumfang gehört dann 
bedeutet dies nicht das es eine gute Lösung ist. Warum wird es wohl in 
anderen Sprachen anders gehandhabt - muß ja wohl einen Grund haben.
Nicht jedes Feature was zum Sprachumfang gehört impliziert automatisch, 
das es ein gutes Features ist.

Frank M. schrieb:
> Verbieten will ich Dir gewiss nichts. Ich wollte Dir nur die
> Peinlichkeit ersparen, Dich weiter zum Affen zu machen.

Ach das lass mal meine Sorge sein. Das kann ich locker aushalten. Als 
viel peinlicher empfinde ich es, wenn man jemanden der bei einer Sache 
Defizite hat ihm diese nicht richtig erklärt sondern eher noch weiter 
dumm anmacht. Das zeugt von besonders hohem Niveau und genau dies kommt 
in diesem Forum leider viel zu oft vor.
Und wenn richtig und ordentlich erklärt wird, dann gibt es auch keine 
Nachfragen und man lernt noch was dabei.

Zeno

von Tim (Gast)


Lesenswert?

Wir warten noch auf deine Quellen, die behaupten sollen, daß if eine 
boolean expression nimmt.

Selbstverständlich nicht irgendein Gekritzel im Internet, sondern etwas 
belastbar vertrauenswürdiges. Ungefähr so wie der bereits zitierte 
Sprachstandard.

von Dussel (Gast)


Lesenswert?

Zeno schrieb:
> Warum wird es wohl in
> anderen Sprachen anders gehandhabt - muß ja wohl einen Grund haben.
Weil es vielseitig, aber damit auch verwirrend ist. In anderen Sprachen 
wird mehr Wert auf Beschränktheit zugunsten von Einfachheit gelegt. C 
lässt sehr viele Freiheiten und jeder kann selber entscheiden, ob er 
sich braucht und will. Unlogisch ist dabei nur wenig.

von Dussel (Gast)


Lesenswert?

Dussel schrieb:
> ob er sich braucht und will
Statt 'sich' sollte da natürlich 'es' stehen.

von Rolf M. (rmagnus)


Lesenswert?

Zeno schrieb:
> Nop schrieb:
>> Für If-Ausdrücke ist der Ausdruck
>> logisch falsch, wenn er 0 ist. Alles andere als 0 ist logisch wahr.
>
> Ich meine das hatte ich schon weiter oben selbst hin geschrieben, aber
> sei's drum.

Ja hast du, aber offenbar hast du nicht verstanden, was es bedeutet.

> Und selbst wenn das in C so ist und zum Sprachumfang gehört dann
> bedeutet dies nicht das es eine gute Lösung ist. Warum wird es wohl in
> anderen Sprachen anders gehandhabt - muß ja wohl einen Grund haben.

Ja. Das ist eben Geschmackssache. In den meisten Sprache ist aber 
dennoch mehr als nur ein Vergleich im if erlaubt. Es muss nur etwas 
sein, dass einen booleschen Wert liefert. Der Unterschied in C ist nur, 
dass dort alle eingebauten Typen sich implizit in boolesche Werte 
konvertieren lassen. Das hat aber nur indirekt mit if zu tun.

> Nicht jedes Feature was zum Sprachumfang gehört impliziert automatisch,
> das es ein gutes Features ist.

Umgekehrt ist nicht jedes Feature, das eine andere Sprache nicht kennt, 
automatisch ein schlechtes.

> Ach das lass mal meine Sorge sein. Das kann ich locker aushalten. Als
> viel peinlicher empfinde ich es, wenn man jemanden der bei einer Sache
> Defizite hat ihm diese nicht richtig erklärt sondern eher noch weiter
> dumm anmacht.

Dass du C nicht perfekt kennst, macht dir keiner zum Vorwurf, sondern 
dass du dir basierend auf nicht vorhandenem Wissen und falschem 
Verständnis eine Meinung bildest und hier quasi lautstark kund tust.
Kennst du die Aussage von Dieter Nuhr zu Leuten, die "von nix ne Ahnung, 
aber zu allem eine Meinung haben"? So in der Art präsentierst du dich 
hier.

von Jens G. (jensig)


Lesenswert?

Zeno schrieb:
> Warum wird es wohl in
> anderen Sprachen anders gehandhabt - muß ja wohl einen Grund haben.

Wenn man in den anderen Sprachen alles genauso machen würde, würde man 
die anderen Sprachen auch C nennen ...

: Bearbeitet durch User
von Dirk B. (dirkb2)


Lesenswert?

Zeno schrieb:
> Dirk B. schrieb:
>> Die Unzulänglichkeit des Autors dies richtig zu Beschreiben und deine
>> Unzulänglichkeit dies zu Verstehen
>
> Ach so! Alle anderen außer Dir sind blööd - so kann man es natürlich
> auch sehen.
>
> Zeno

Das ist nicht meine Sichtweise, sondern deine.

von W.S. (Gast)


Lesenswert?

Rufus Τ. F. schrieb:
> C ist ein anspruchsvolles Werkzeug, das Übung und Erfahrung erfordert,
> um es beherrschen zu können.

ich werde so langsam böse.

C ist ein schlechtes Werkzeug, was man nur deshalb benutzt, weil die 
Compilerhersteller einem kein besseres Werkzeug liefern (nicht mal für 
richtig GELD). Darum!

Und eines solltest du dir mal ins Notizbuch schreiben: Keine 
Programmiersprache dieser Welt ist etwas, das irgend einen ANSPRUCH 
erheben darf.

Umgekehrt wird ein Schuh draus:

Ich, der Entwickler stelle Ansprüche und Maschinen und Dinge aller Art 
sollen meinen Ansprüchen möglichst gut genügen. So herum.

Man kann es auch plakativer fassen: Die Maschine soll dem Menschen 
dienen und nicht umgekehrt.

Merk dir das mal. Es ist wirklich wichtig - auch wenn du das im Eifer 
dieses albernen Disputes aus den Augen verloren haben solltest.

W.S.

von Ludwig (Gast)


Lesenswert?

@ W.S.

Für den Überblick über das Jammertal der Sprache C, gibt es zum Glück 
einen Profi wie dich.

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

W.S. schrieb:
> C ist ein schlechtes Werkzeug, was man nur deshalb benutzt, weil die
> Compilerhersteller einem kein besseres Werkzeug liefern

Es ist doch noch gar nicht Freitag, und hier ist nicht das Heise-Forum.

Wenn Dich der Umgang mit C überfordert (oder meinetwegen auch 
unterfordert), dann lass es halt sein, statt Dich darüber aufzuregen. 
Tut Deiner Magensäure auch nicht gut, all' die Aufregung.

> Und eines solltest du dir mal ins Notizbuch schreiben: Keine
> Programmiersprache dieser Welt ist etwas, das irgend einen ANSPRUCH
> erheben darf.

Aha. Jedes Werkzeug erhebt irgendeinen Anspruch. Das ist so.

Und manche Werkzeuge sind anspruchsvoller als andere; ein Hammer ist mit 
weniger feinmotorischen Fertigkeiten verwendbar als eine Nadelfeile.

Und so ist das bei Programmiersprachen auch - auch die sind Werkzeuge, 
und natürlich haben die auch unterschiedliche Ansprüche.

> Ich, der Entwickler stelle Ansprüche und Maschinen und Dinge aller Art
> sollen meinen Ansprüchen möglichst gut genügen.

Dann musst Du die Deinen Fähigkeiten (nicht Ansprüchen!) 
entsprechenden Maschinen und Dinge aller Art aussuchen, und damit 
arbeiten.

Aber nicht darüber herziehen, wie "schlecht" doch Maschinen und Dinge 
sind, die nicht Deinen Fähigkeiten entsprechen.

Klingt hart, aber so ist das Leben.

von (prx) A. K. (prx)


Lesenswert?

W.S. schrieb:
> weil die Compilerhersteller einem kein besseres Werkzeug liefern

Dies trifft allenfalls auf Mikrocontroller zu.
Und selbst da gibt es nicht selten auch andere Sprachen.

von Christopher C. (trihexagon)


Lesenswert?

Nop schrieb:
> Christopher C. schrieb:
>> Aha und was macht C11 grundsätzlich anders als C99 oder C89? Das Gremium
>> macht bewusst keine großen Änderungen. Nun zu behaupten C11 sei eine
>> "Weiterentwicklung" von C99 ist eher ein Witz.
>
> Dinge, die gut sind, muß man auch nicht weiterentwickeln, weil sie dann
> nämlich nach einem Optimalstadium auch wieder schlechter werden.
> Fortschritt gibt es nicht unendlich. Pure Ketzerei, weiß ich, aber ich
> bin froh, daß man C nicht unnötig versaut. Wenigstens ETWAS, das nach
> wie vor gut brauchbar ist.
>
> Wofür steht die 11 bei C++11? Für die Anzahl der Füße, die man an C++
> angepappt hat, in der Hoffnung, einen besseren Octopus zu bekommen.

Da stimme ich dir zu. Ich habe auch gar nicht kritisiert, dass sich C 
nicht mehr weiterentwickelt. Die Entscheidung des Gremiums kann ich 
sogar nachvollziehen. Nur muss man das auch so festhalten und darf nicht 
behaupten, dass C11 eine Weiterentwicklung im klassischen Sinne ist. 
Darum gings doch.

In Rust (wie auch in Go) gibt's übrigens eine extra Endlosschleife.
1
loop {
2
  foobar++;
3
}

von W.S. (Gast)


Lesenswert?

Yalu X. schrieb:
> if (index % 2)...

ohrenlangzieh!


> Mit dem ?:-Operator besteht dieses Problem überhaupt nicht:

Aber dafür kommt das Verstehenmüssen dieses Operators auf, siehe unten. 
Hier fragt sich jemand was es mit der unverständlichen Formulierung von 
for(;;) auf sich hat - hast du das ganz und gar vergessen?


Yalu X. schrieb:
> Jetzt steht aber der Codeabschnitt A zweimal da. Jemand, der das
> Programm liest, wird – wenn überhaupt – erst nach längerem Hinsehen
> erkennen, dass da ein Stück Code vor der Schleife mit einem Teil des
> Codes in der Schleife übereinstimmt.

Yalu, so manchmal frag ich mich, womit du dein Geld verdienst. Den Fall, 
den du mit "Codeabschnitt A zweimal" beschrieben hast, hat man dediziert 
im Zuge von digitaler Signalverarbeitung mit Systemen ohne B-Cache. Da 
macht man es genau so, wenn man keinen Indexgenerator wie bei echten 
DSP's hat. Das ist dan gewollt so, weil es - generell gesagt - auf 
gerade Indizes führt. Die Alternative wäre, den Kruscht hintendran zu 
hängen. Na eben so ähnlich, wie es mit dem String-Compare in allen 
bekannten Bibliotheksfunktionen gemacht wird.

Aber um sowas geht es hier ja nicht. Im hier eher gewöhnlichen Umfeld 
wäre inmitten so einer Schleife ein simples return am ehesten angesagt - 
wenn so eine Schleife tatsächlich derart gestaltet wäre (was ich aber 
hier für an den Haaren herbeigezerrt einschätze).

So, nun zu dir:
Der ? Operator ist überhaupt nicht intuitiv. Sowas muß verinnerlicht 
werden und ist genau deshalb schlecht. Ein if /else ist hingegen 
intuitiv - und genau darauf kommt es an. Das Beispiel von Rufus ist 
gelinde gesagt miserabel. Ich würde SO nie und nimmer programmieren.

Ich sag's mal so: der ? Operator ist ein typischer C-Faulheits-Operator 
- eben nur dazu gedacht, ein if else zusammenziehen zu können. Da spart 
man grandiose 5 Buchstaben. Halleluja! Nein, sowas ist definitiv NICHT 
lesbarer als ein sauberes if else. Auch wenn du das behauptest.

So. Genug damit, ich guck mal lieber in's Weinglas, heute mit einem 
richtig guten Roten aus Dolgesheim.

W.S.

von (prx) A. K. (prx)


Lesenswert?

W.S. schrieb:
> Ich sag's mal so: der ? Operator ist ein typischer C-Faulheits-Operator

Er hat seinen Ursprung in Präprozessor-Makros. Versuch mal, getc() ohne 
Inline-Funktionen laufzeiteffizient zu implementieren.

Zudem sind durchweg alle Programmiersprachen nur entstanden, weil die 
Leute zu faul waren, die Programme bitweise per Konsolschalter in den 
Speicher zu wuchten.

: Bearbeitet durch User
von W.S. (Gast)


Lesenswert?

Carl D. schrieb:
> Dann besorg dir einen Compiler, der was taugt. Der von mir benutzte ist
> kostenlos zu bekommen und hat kein Problem damit Anfängerfehler zu
> finden.

Du bist mal wieder auf dem Holzweg.

Sowas sind ausdrücklich KEINE Anfängerfehler, sondern sowas (und 
ähnliches) passiert jedem, der etwas anderes ist als Maschinensklave. 
Wer sein gesamtes Arbeitsleben nur mit C schreiben verbringt, kommt 
sicherlich zu deiner Meinung.

Aber jeder normale Entwickler hat weitaus mehr um die Ohren als nur die 
C Syntax. Und da rutschen einem solche Dinge elleweil mal durch - beim 
Schreiben in Pascal passiert mir oft genug das Umgekehrte, daß ich 
gelegentlich mal eine C-Wendung hinschreibe - aber da meckert einen der 
Compiler an genau der richtigen Stelle an.

Also laß derartige Mutmaßungen, sie sind falsch, albern und 
scheuklappig.

W.S.

von Zeno (Gast)


Lesenswert?

Rolf M. schrieb:
> Dass du C nicht perfekt kennst, macht dir keiner zum Vorwurf, sondern
> dass du dir basierend auf nicht vorhandenem Wissen und falschem
> Verständnis eine Meinung bildest und hier quasi lautstark kund tust.
> Kennst du die Aussage von Dieter Nuhr zu Leuten, die "von nix ne Ahnung,
> aber zu allem eine Meinung haben"? So in der Art präsentierst du dich
> hier.

Das hab ich ja noch gar nicht bemerkt.

Es freut mich ja für Dich das Du offensichtlich von allem eine Ahnung 
hast.

Ich habe in meinem 2. Post lediglich kundgetan das ich ab und an über 
die 2 "==" gestolpert bin und mir da schon einen Wolf gesucht habe  und 
das ich da der Meinung bin das dies ein syntaktischer Fehler ist und 
dieser als solcher eigentlich auch angezeigt werden sollte. Sicher man 
hätte schon daran denken können, das C in Ermangelung eines boolschen 
Datentyps alles als logisch wahr interpretiert was verschieden von 0 ist 
und der Compiler deshalb dies als syntaktischen Fehler nicht erkennen 
kann. Es ist halt ein Designfehler von C auf diesen wichtigen Datentyp 
zu verzichten. Andere gängige Sprachen, u.a. auch C++, kennen diesen 
Datentyp. Es erhebt sich jetzt natürlich die Frage, warum hat man es bei 
C++ eingeführt. Sicher nicht deshalb damit man ein Schlüsselwort mehr 
lernen muß.
Und das ist nicht der einzige Designfehler in C. Das geht weiter mit den 
fehlenden Strings die durch das unsägliche Zeichenarray dargestellt 
werden müssen, welches zu allem Überfluß noch durch das Nullzeichen 
abgeschlossen werden muß, weil C nicht wirklich mit Arrays umgehen kann 
(sage nicht nur ich) und das Stringende glatt verpassen würde.
Das sind Designfehler in C die einem sofort auffallen, wenn man von 
einer anderen Sprache kommt. Dazu muß man kein C Guru sein. Der muß man 
allerdings sein, wenn man die entarteten C-Konstrukte verstehen will.

Es ist unstreitig, daß man bei µC Programmierung nicht um C herum kommt, 
aber die Schwächen in bleiben bestehen und die braucht man auch nicht 
schön reden.

mec schrieb:
> W.S. schrieb:
>> Kurzum: C is nicht mehr renovierungsfähig. Man kann damit leben, in
>> vielen Gebieten wie µC-Programmierung muß man das auch mangels Tools für
>> andere Sprachen und C reicht eigentlich auch für recht vieles völlig
>> aus, aber eine wirklich gute Programmiersprache ist C wahrlich nicht.

Ich kann da eigentlich nur W.S. beipflichten. Er hat Recht auch wenn es 
den einen oder anderen schmerzt.


Zeno

von Nop (Gast)


Lesenswert?

W.S. schrieb:
> beim
> Schreiben in Pascal passiert mir oft genug das Umgekehrte, daß ich
> gelegentlich mal eine C-Wendung hinschreibe

Weißte, ich hab mit Pascal angefangen zu programmieren, damals noch an 
der Schule im Informatikkurs. Also nicht nur "hello world", und nicht 
nur etwas if/then/else, sondern schon auch Sachen wie verkettete Listen 
und Sortieralgorithmen. Und die eine oder andere Anwendung in 
Eigeninitiative.

Als Lehrsprache ist Pascal gut. Aber es hat seinen Grund, wieso die 
Wirth-Sprachen praktisch weitgehend geflopt sind.

Im Gegensatz zu Pascal wurde C nicht im akademischen Elfenbeinturm 
entworfen, sondern von Programmierern für Programmierer, und im Sinne 
von "eat your own dogfood" hat es sich dann auch bewähren müssen.

Ich hab ein paar Monate gebraucht, um mit C warmzuwerden - und danach 
wollte ich nie wieder zu Pascal zurück. Den Müslifaktor finde ich im 
Vergleich mit C einfach unerträglich.

von W.S. (Gast)


Lesenswert?

Rufus Τ. F. schrieb:
> Nein. Da liegst Du falsch. if erwartet einen Ausdruck, der einen Wert
> hat. Und eine Zuweisung hat auch einen Wert.
>
> Das ist kein syntaktischer Fehler, das ist legales C.

Formal hast du Recht, aber es ist einer der vielen Geburtsfehler von C 
und hätte schon seit langem ausgemerzt gehört.

So herum.

Daß moderne Compiler drüber meckern, ist eine Hilfe, die bei der 
miserablen Sprachdefinition auch dringend nötig ist.

Kurzum, der Sinn eines if besteht darin, eine Verzweigung anhand einer 
Bedingung zu bewerkstelligen und das ist intuitiv eben immer ein 
Vergleich nach dem Motto apfel=birne oder apfel<>birne (zum Verstehen: 
größer oder kleiner, also NICHT gleich, das ! als "un" zu verstehen ist 
auch so ein Dogma, das unlogisch ist). Das Konstrukt "Wert eines 
Ausdruckes" und "Wert ungleich null" ist auch so ein Dogma in 
Ermangelung eines Boolean Typs.

W.S.

(wenn das hier so weitergeht, ist mein Glas leer, bevor ich allen Unsinn 
gelesen hab..)

von Yalu X. (yalu) (Moderator)


Lesenswert?

W.S. schrieb:
>> Mit dem ?:-Operator besteht dieses Problem überhaupt nicht:
>
> Aber dafür kommt das Verstehenmüssen dieses Operators auf, siehe unten.

Der ist aber auch so etwas von überunendlich kompliziert zu verstehen :)

> Der ? Operator ist überhaupt nicht intuitiv.

Genauso wenig wie Programmieren insgesamt intuitiv ist.

Auch wenn das viele nicht glauben mögen: Programmieren muss man
tatsächlich lernen, egal in welcher Sprache. Und dazu gehört es eben
auch, die 1 bis 3 Sätze in einem C-Buch durchzulesen, die den
?:-Operator beschreiben.

W.S. schrieb:
> Das Beispiel von Rufus ist gelinde gesagt miserabel. Ich würde SO nie
> und nimmer programmieren.

Natürlich nicht, du würdest dafür ein Konstrukt mit mindestens zwei
Gotos basteln, weil das ja viel logischer ist :)

> Ich sag's mal so: der ? Operator ist ein typischer C-Faulheits-Operator
> - eben nur dazu gedacht, ein if else zusammenziehen zu können. Da spart
> man grandiose 5 Buchstaben.

Du hast also den Unterschied zwischen einem Ausdruck und einer Anweisung
immer noch nicht verstanden.

> ich guck mal lieber in's Weinglas

Aber bitte nicht wieder zu tief ;-)

von W.S. (Gast)


Lesenswert?

Rolf M. schrieb:
> ist eine mögliche Anwendung. Ohne die Zuweisung im while müßte man
> schreiben
> result = fread(buf, 1, BUFSIZE, file);
> while (result)
> {
>     // arbeite mit buf
>     result = fread(buf, 1, BUFSIZE, file);
> }
>
> // Fehlerbehandlung
>
> und da haben wir wieder zwei identische Funktionsaufrufe

So langsam wirds peinlich.
Kennst du eigentlich sowas wie do while?
Nö? dann lies mal dort: 
"http://www.c-howto.de/tutorial-schleifen-do.html";

W.S.

von Zeno (Gast)


Lesenswert?

W.S. schrieb:
> wenn das hier so weitergeht, ist mein Glas leer, bevor ich allen Unsinn
> gelesen hab.

Nicht aufregen - genieße lieber den Traubensaft.

Du wirst die Leute hier nicht bekehren, das diese nicht über den (C-) 
Tellerand hinweg schauen wollen oder doch besser können.

Zeno

von Nop (Gast)


Lesenswert?

Zeno schrieb:
> Es ist halt ein Designfehler von C auf diesen wichtigen Datentyp
> zu verzichten.

Nein, ist es nicht. Er ist schlichtweg überflüssig. Jedenfalls ist das 
die Sicht, die beim Design von C vertreten wurde. Das war kein Fehler 
und auch kein Versehen, sondern eine Entscheidung.

Das gilt übrigens auch für eine ganze Menge vom undefined behaviour, was 
aus gutem Grund so ist - nur daß das eben erst logisch wird, wenn man 
die Hintergründe versteht. Und da muß man schon sagen, daß Kerninghan 
und Ritchie ETWAS mehr Ahnung hatten als Programmier-Anfänger. Die haben 
die Sprache auch nicht für Programmier-Anfänger gemacht - für die gab es 
auch damals schon BASIC (das B steht für "Beginner").

> Und das ist nicht der einzige Designfehler in C. Das geht weiter mit den
> fehlenden Strings die durch das unsägliche Zeichenarray dargestellt
> werden müssen

Müssen sie nicht. Es steht Dir durchaus frei, in C auch Pascal-Strings 
zu bauen. Diese haben allerdings dann den systematischen Nachteil, daß 
Du nicht einfach mit Pointer-Increment innerhalb des Strings springen 
kannst UND dabei immer noch einen gültigen Reststring hast. Insbesondere 
kannst Du nicht den Reststring als Pointer an andere Funktionen 
weiterreichen.

von Dussel (Gast)


Lesenswert?

Yalu X. schrieb:
> W.S. schrieb:
>>> Mit dem ?:-Operator besteht dieses Problem überhaupt nicht:
>>
>> Aber dafür kommt das Verstehenmüssen dieses Operators auf, siehe unten.
>
> Der ist aber auch so etwas von überunendlich kompliziert zu verstehen :)
Vor Allem ist die Argumentation so geil. Variablen muss man auch erstmal 
verstehen, also sind Variablen schlecht. Die Abbruchbedingung muss man 
verstehen, Abbruchbedingungen sind also auch schlecht. Rückgabewerte von 
Funktionen muss man verstehen. Die sind also auch schlecht. Genauso wie 
Arrays.

Das heißt, W.S.'s Sprache darf unter anderem schonmal keine Variablen, 
keine Abbruchbedingungen und keine Rückgabewerte von Funktionen und 
keine Arrays enthalten.

W.S. schrieb:
> So langsam wirds peinlich.
Gut erkannt. Dann hör doch endlich mal auf.

Zeno schrieb:
> Du wirst die Leute hier nicht bekehren, das diese nicht über den (C-)
> Tellerand hinweg schauen wollen oder doch besser können.
"Einer? Hunderte!" (Für die, die den entsprechenden Witz kennen.)

von Nop (Gast)


Lesenswert?

Christopher C. schrieb:
> In Rust (wie auch in Go) gibt's übrigens eine extra Endlosschleife.

Wer drauf steht, kann das in C auch haben. Dazu muß man das nicht als 
Sprachdefinition aufnehmen.
1
#define loop for(;;)
2
...
3
loop
4
{
5
   endless_stuff();
6
}

(die for-Variante, weil die auch durch Lint durchgeht.)

von (prx) A. K. (prx)


Lesenswert?

Zeno schrieb:
> Andere gängige Sprachen, u.a. auch C++, kennen diesen
> Datentyp.

... ohne in dieser Frage was in der Sache zu ändern (C++).

> Das sind Designfehler in C die einem sofort auffallen, wenn man von
> einer anderen Sprache kommt.

Ich teile die Kritik. Nur sehe ich das Problem weniger in der Sprache 
selbst, als in deren Anwendung in Bereichen, für die sie nicht (mehr) 
geeignet ist.

Multics adressierte in seiner Komplexität nur damalige Grossrechner. Bei 
dessen Programmiersprache PL/I war es nicht anders. Sowohl Unix (sieht 
man schon im Namen) als auch C waren das Gegenmodell dazu. Denn an 
Grossrechner kam nicht jeder ran, Minicomputer waren weit leichter 
verfügbar.

Die Folge war Unix und dessen Programmiersprache C. Diese entwickelte 
sich aus Sprachen wie B und BCPL, die noch simpler waren, zur 
Implementierung eines einfachen Betriebssystems. Beides, Betriebssystem 
und Compiler, sollten auf den Minicomputern implementiert werden können. 
Sichere Netzwerkanwendungen hatte niemand auf dem Radar.

Wirth machte das auch nicht anders als Ritchie. Zu einem neuen Problem 
entwarf er eine neue Sprache. Pascal hatte er ausschliesslich als 
Lehrsprache entwickelt und für mehr war es in seiner damaligen Form auch 
nicht zu gebrauchen.

C hatte in diesem Sinn das Pech, über den universitären Siegeszug von 
Unix als universelle Programmiersprache für Gott und die Welt eingesetzt 
zu werden. Und es lebt in Dimensionen fort, für die es weder gedacht 
noch gut geeignet war. Nicht weil es gut war, sondern weil es verfügbar 
war und in seiner begrenzten Komplexität auf jene Maschinen passte, an 
die jeder rankam. Der Quellcode von Betriebssystem und Compiler war 
verfügbar und jeder schraubte daran herum - um die rechtliche Bewertung 
durften sich eine Generation später die Anwälte streiten, damals 
interessierte das kaum jemanden.

: Bearbeitet durch User
von Zeno (Gast)


Lesenswert?

Nop schrieb:
> Nein, ist es nicht. Er ist schlichtweg überflüssig.

Das meinst Du! Du willst Dich doch nicht etwa mit Herrn Wirth oder van 
Rossum vergleichen. Die beiden dürften Dir bei weitem überlegen sein und 
werden ihre Gründe haben warum sie unter anderem auch diesen Datentyp in 
ihre Sprachen implementiert haben.
Im übrigen maße ich mir nicht an schlauer als K&R zu sein und stelle 
auch nicht Abrede, daß sie für ihre Leistung Respekt verdienen. Aber es 
sind keine Götter denen man huldigen muß - gilt auch für die von mir zu 
vor genannten 2 Herren.

Nop schrieb:
> Diese haben allerdings dann den systematischen Nachteil, daß
> Du nicht einfach mit Pointer-Increment innerhalb des Strings springen
> kannst UND dabei immer noch einen gültigen Reststring hast. Insbesondere
> kannst Du nicht den Reststring als Pointer an andere Funktionen
> weiterreichen.

Speziell dieses Feature habe ich in meinen (Pascal-) Projekten immer 
vermißt.

Zeno

von (prx) A. K. (prx)


Lesenswert?

Zeno schrieb:
> Im übrigen maße ich mir nicht an schlauer als K&R zu sein und stelle
> auch nicht Abrede, daß sie für ihre Leistung Respekt verdienen.

Kannst dich auf Ritchie beschränken. Kernighan schrieb zwar das Buch 
mit, war aber erklärtermassen kein Schöpfer von C.

: Bearbeitet durch User
von Zeno (Gast)


Lesenswert?

A. K. schrieb:
> Die Folge war Unix und dessen Programmiersprache C. ....

Du hast es in Deinem Post auf den Punkt gebracht und den historischen 
Werdegang beschrieben - uneingeschränkte Zustimmung. Leider sehen das 
hier die meisten Leute anders.

Zeno

von Zeno (Gast)


Lesenswert?

A. K. schrieb:
> Kannst dich auf Ritchie beschränken. Kernighan schrieb zwar das Buch
> mit, war aber erklärtermassen kein Schöpfer von C.

Danke für den Hinweis. Das war mir so nicht bekannt, da beide immer in 
einem Atemzug genannt werden.

Zeno

von Nop (Gast)


Lesenswert?

Zeno schrieb:
> Das meinst Du! Du willst Dich doch nicht etwa mit Herrn Wirth oder van
> Rossum vergleichen.

Das meine nicht ich, sondern ich schrieb, daß das die Designentscheidung 
bei C war. Und mal ehrlich, Wirths Schöpfungen mögen akademisch ja toll 
sein, sind aber praktisch weitgehend geflopt. C nicht.

Allerdings bringt es schon was, wenn man Programmieren nicht mit C 
lernt, sondern mit Pascal. Man macht dann einfach in C weniger Fehler. 
Deswegen meinte ich ja schon, Pascal ist eine gute Lehrsprache.

Aber C finde ich den genialsten portablen Makro-Assembler überhaupt. 
Ohne mich mit Wirth auf eine Stufe stellen zu wollen (der ist natürlich 
in einer anderen Liga), aber wie ich schon meinte, den Müslifaktor bei 
Pascal finde ich unerträglich.

Ich habe nach dem Umstieg von Pascal auf C Pascal nie mehr vermißt. Ist 
wie mit ner Ex.

von Nop (Gast)


Lesenswert?

A. K. schrieb:
> Wirth machte das auch nicht anders als Ritchie. Zu einem neuen Problem
> entwarf er eine neue Sprache.

Mit Lisp hätte er sich das auch sparen können. (;

von W.S. (Gast)


Lesenswert?

Nop schrieb:
> Als Lehrsprache ist Pascal gut. Aber es hat seinen Grund, wieso die
> Wirth-Sprachen praktisch weitgehend geflopt sind.
>
> Im Gegensatz zu Pascal wurde C nicht im akademischen Elfenbeinturm
> entworfen, sondern von Programmierern für Programmierer, und im Sinne
> von "eat your own dogfood" hat es sich dann auch bewähren müssen.

Ach du..
Die Gründe für C sehe ich zu 99% im außertechnischen Bereich. Die 
Schwierigkeit, mit C zurecht zu kommen, ist gewollt und dein "mögen" hat 
einen Geschmack nach "endlich bin auch ich elitär" - ich weiß, sowas 
steckt in jedem Manne mental drin.

Aber ich guck nach vorn, und da sehe ich kein Vorwärtskommen für C - im 
Gegensatz zu Pascal. Guck dir doch mal beides zum Vergleich an: der 
erste und wohl letzte Markstein bei C war ANSI, um von dem K&R-Kruscht 
weg zu kommen. War auch nötig. Programmiere mal mit nem klassischen 
Sozobon-Compiler, da merkst du den Schmerz der Anfänge. Aber das war's 
dann auch schon bei C. Alles Spätere ist peanuts.
Und nun guck dir Pascal in seiner heutigen Form (FPC oder Embarcadero) 
an. Merkst du da was? Es ist nicht mehr wie dunnemals Wirth's, es kann 
alles, was C kann und es kann darüber hinaus auch alles, was C nicht 
kann. Pascal ist zukunftsfähig, C nicht.

Es ist immer eine sowohl heikle als auch dumme Sache, von dem 
"Gemochtwerden" auf die Qualitäten zu schließen, es ist nicht so, daß 
die Masse Recht hat, sie kann nämlich auch auf dem Holzweg sein. Ich 
sag's mal mit einem Zitat "die Quote ist der ultimative Sieg des 
Proletariats".

Oder anders herum: Du magst C mehr als Pascal, aber kann C deshalb 
Objektorientiertheit? Oder Exceptions? Oder Strings? nein, natürlich 
nicht. Man könnte allenfalls sowas zu Fuß nachbilden (geht in Assembler 
auch...), aber die Sprache C selbst gibt es nicht her. Das "Mögen" ist 
subjektiv, genannte Kriterien sind objektiv.

Natürlich haben viele kluge Köpfe schon seit langer Zeit gemerkt, daß C 
- so wie es ist - weder den heutigen Nöten gerecht wird noch wirklich 
zukunftsfähig ist. Genau deshalb wurden (und werden) alle möglichen 
Abwandlungen erfunden: C++, C#, Java und anderes Zeugs. Vielleicht kommt 
eines Tages dabei etwas wirklich Tragfähiges dabei heraus. Vielleicht.

W.S.

von Rolf M. (rmagnus)


Lesenswert?

W.S. schrieb:
> Sowas sind ausdrücklich KEINE Anfängerfehler, sondern sowas (und
> ähnliches) passiert jedem, der etwas anderes ist als Maschinensklave.

[...]

> Also laß derartige Mutmaßungen, sie sind falsch, albern und
> scheuklappig.

Dito. Du schließt hier offenbar von dir auf andere.

Zeno schrieb:
> Es freut mich ja für Dich das Du offensichtlich von allem eine Ahnung
> hast.

Wo glaubst du denn, das gelesen zu haben?
Ich wiederhole nochmal:

> Rolf M. schrieb:
>> Dass du C nicht perfekt kennst, macht dir keiner zum Vorwurf

> Andere gängige Sprachen, u.a. auch C++, kennen diesen Datentyp. Es erhebt
> sich jetzt natürlich die Frage, warum hat man es bei C++ eingeführt.
> Sicher nicht deshalb damit man ein Schlüsselwort mehr lernen muß.

Du weißt aber, dass sich im Bezug auf die Nutzung von if durch die 
Einführung von bool in C++ genau gar nichts geändert hat? Es gilt genau 
das selbe, wie in C. Wie oben schon geschrieben ist der Grund, dass 
Zuweisungen in einem if erlaubt sind nicht das Fehlen eines eigenen 
Datentyps für boolesche Werte, sondern die Tatsache, dass jeder Wert 
eines eingebauten Typs implizit als boolescher Wert verwendet werden 
kann sowie die Tatsache, dass eine Zuweisung in C ein Ausdruck ist und 
somit einen Wert liefert. Das kann man mögen oder auch nicht. In neueren 
Sprachen wird zumindest die implizite Konvertierung meist nicht gemacht.

> Und das ist nicht der einzige Designfehler in C. Das geht weiter mit den
> fehlenden Strings die durch das unsägliche Zeichenarray dargestellt
> werden müssen, welches zu allem Überfluß noch durch das Nullzeichen
> abgeschlossen werden muß, weil C nicht wirklich mit Arrays umgehen kann
> (sage nicht nur ich) und das Stringende glatt verpassen würde.

Ja, Stringhandling ist etwas, das ich in C auch nicht machen möchte.

W.S. schrieb:
> Kurzum, der Sinn eines if besteht darin, eine Verzweigung anhand einer
> Bedingung zu bewerkstelligen und das ist intuitiv eben immer ein
> Vergleich nach dem Motto apfel=birne oder apfel<>birne (zum Verstehen:
> größer oder kleiner, also NICHT gleich, das ! als "un" zu verstehen ist
> auch so ein Dogma, das unlogisch ist).

Langsam geht's mir auf den Zeiger, wie du ständig wahlfrei irgendwelche 
Dinge hernimmst und einfach mal für unlogisch erklärst - natürlich wie 
immer ohne Begründung. != ist kein bischen logischer oder unlogischer 
als <>, sondern einfach nur eine andere, aus deiner Sicht ungewohnte 
Schreibweise. Und nach dem Motto "was der Bauer nicht kennt, frisst er 
nicht" lehnst du sie eben ab. Das ist alles.

> (wenn das hier so weitergeht, ist mein Glas leer, bevor ich allen Unsinn
> gelesen hab..)

Ich hoffe nur, dass der Unsinn, den du dadurch schreibst nicht noch 
größer wird.

W.S. schrieb:
> Rolf M. schrieb:
>> ist eine mögliche Anwendung. Ohne die Zuweisung im while müßte man
>> schreiben
>> result = fread(buf, 1, BUFSIZE, file);
>> while (result)
>> {
>>     // arbeite mit buf
>>     result = fread(buf, 1, BUFSIZE, file);
>> }
>>
>> // Fehlerbehandlung
>>
>> und da haben wir wieder zwei identische Funktionsaufrufe
>
> So langsam wirds peinlich.

Allerdings. Du machst dich wirklich gerade zum Affen. Vielleicht doch 
schon zuviel Wein intus?

> Kennst du eigentlich sowas wie do while?

Ja, und im Gegensatz zu dir weiß ich auch, wie es funktioniert und dass 
man damit das Problem auch nicht ohne weitere Klimmzüge lösen kann.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.