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.

von Zeno (Gast)


Lesenswert?

Nop schrieb:
> Und mal ehrlich, Wirths Schöpfungen mögen akademisch ja toll
> sein, sind aber praktisch weitgehend geflopt. C nicht.

Hast Du mal die Post von A.K. gelesen. Er hat doch verständlich erklärt.

Ach und meinst Du Embacadero (ehemals Borland) würde immer noch 
Pascalcompiler bauen und zu horrenten Preisen anbieten, wenn es dafür 
keinen Markt gäbe?
Also so ein großer Flop scheint Pascal nun auch wieder nicht zu sein. 
Und auch wenn Du es vielleicht nicht wahrhaben willst Pascal oder besser 
das was besagter Firma angeboten wird, hat sich gegenüber dem alten 
Pascal von Wirth erheblich weiter entwickelt. Aber eines ist auf jeden 
Fall geblieben : Der Compiler ist immer noch sehr restriktiv und haut 
einem gehörig auf Finger wenn man Mist verzapft.

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

Schön für Dich.

Zeno

von (prx) A. K. (prx)


Lesenswert?

Ich kam Anfang der 80er zu C. Da besass ich irgendwann ein 68000 System 
ohne Betriebssystem und ohne Programmiersprache. Dieses System entsprach 
in seiner Grössenordnung ungefähr einer PDP-11 der 70er Jahre.

Und da gab es einen C Compiler für 68000, den ein anderer Studi als 
Diplomarbeit aus einem C Compiler für PDP-11 und andere Zielsysteme 
gestrickt hatte, und der lief auf einer VAX von der Uni. Quellcode war 
verfügbar, Zugang zur VAX auch.

Das Ergebnis war ein einfaches Betriebssystem für das 68000 System und 
ein daran adaptierter Compiler, Assembler, Linker. Zusammen mit einem 
Freund entwickelt.

Das ist ein für damalige Verhältnisse durchaus typischer Werdegang. Man 
nimmt was man hat und lässt sich von dem inspirieren, was man kennt. In 
dieser Dimension war C völlig passend. Kein Internet, nicht einmal 
Usenet. Der Compiler startete von Floppy-Disk und war schnell.

Irgendwann kam dann Ada, weil dem DOD der Software-Wildwuchs auf die 
Nerven ging. Die Sprache adressierte erkennbar genau diesen mir 
wohlbekannten Bereich, von lowlevel I/O bis Betriebssystem und dessen 
Grundanwendungen. Es gab damals aber einen entscheidenden Unterschied: 
Die ersten Ada Compiler waren wahre Monster und nicht praktisch 
einsetzbar. Das "Plonk" konnte man regelrecht hören, das ging nicht nur 
mir so. C war und blieb praktischer.

von Christopher C. (trihexagon)


Lesenswert?

@Zeno Bitte stapel mal ein bisschen tiefer, für das, dass du sowas 
ablässt:

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.

reißt du jetzt ganz schön die Klappe auf. Kannst du wirklich C? Weil die 
Aussage ist ziemlich, sagen wir mal, kurios...

von Zeno (Gast)


Lesenswert?

Rolf M. schrieb:
> 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?

Das weis ich schon. C++ ist an vielen Stellen halt immer noch C. Man hat 
halt Objekte hinzugefügt, Strings eingeführt und einiges mehr, aber man 
hat es versäumt, das was mangelhaft ist ohne wenn und aber 
rauszuschmeißen.

Und man kann dies weiter zu C# spinnen. Auch da hat man wieder viel 
Neues eingeführt, darunter auch viele Sachen die einem das Leben 
leichter machen. Aber bei einigen neuen Sachen ist man auch wieder nicht 
konsequent gewesen und hat es von Anfang bis Ende ordentlich 
"durchgestylt". Ergebnis dieses Flickwerkes ist es natürlich, das man 
wieder erst mal in diverse Sackgassen rennt. Und ja es ist im Grundkern 
immer noch C obwohl es hier hätte konsequent rausschmeißen können. Die 
Hardwarenähe die mir C bietet werde ich in C# wohl eher nicht brauchen, 
denn keiner wird damit z.B. ein Programm für einen µC schreiben.


Zeno

von (prx) A. K. (prx)


Lesenswert?

Manche Kritik hier leidet ein wenig am Ansatz. Denn es ist sinnlos, sich 
an Trivialitäten wie for(;;) und while(1) aufzuhängen. Das ist einfach 
nur Kinderkram. Ob man das nun elegant findet oder nicht, wer darüber 
länger als 1min stolpert hat ein anderes Problem.

Längere Streiterei darüber führt deshalb allzu leicht zur Einschätzung 
"der spinnt doch". Und wenn man diesen Ruf mal weg hat ...

NB: Eine Sprache zu verwenden heisst nicht, sie auch wirklich gut zu 
finden. Und irgendwann wird es zur Gewohnheit. The devil you know.

: Bearbeitet durch User
von Christopher C. (trihexagon)


Lesenswert?

Zeno schrieb:
> Und man kann dies weiter zu C# spinnen. Auch da hat man wieder viel
> Neues eingeführt, darunter auch viele Sachen die einem das Leben
> leichter machen. Aber bei einigen neuen Sachen ist man auch wieder nicht
> konsequent gewesen und hat es von Anfang bis Ende ordentlich
> "durchgestylt". Ergebnis dieses Flickwerkes ist es natürlich, das man
> wieder erst mal in diverse Sackgassen rennt. Und ja es ist im Grundkern
> immer noch C obwohl es hier hätte konsequent rausschmeißen können. Die
> Hardwarenähe die mir C bietet werde ich in C# wohl eher nicht brauchen,
> denn keiner wird damit z.B. ein Programm für einen µC schreiben.

Erzähl mal mehr darüber. C# hat nämlich außer der Syntax sehr wenig mit 
C gemein (dafür mit Java). C# hat eigentlich gar keine "Hardwarenähe", 
dass es Zeiger gibt, wissen die Wenigsten, weils auch praktisch keiner 
braucht (außer im Zusammenspiel mit nativen Code). Die gibts nur im 
unsafe Block und die Zeigerarithmetik ist extrem eingeschränkt.

von Paul B. (paul_baumann)


Lesenswert?

Christopher C. schrieb:
> C# hat eigentlich gar keine "Hardwarenähe",
> dass es Zeiger gibt, wissen die Wenigsten, weils auch praktisch keiner
> braucht (außer im Zusammenspiel mit nativen Code).

Zeiger? Die könnten beim Schreiben eines Uhrenprogrammes nützlich sein.

O.T.

Eigentlich gehört doch hier ein Zaun drum mit Warnschildern:

"Achtung! C-Fetischisten

Nicht füttern oder tränken!

Insassen werfen mit Operatoren um sich!"

MfG Paul

: Bearbeitet durch User
von Nop (Gast)


Lesenswert?

W.S. schrieb:

> 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.

Nö, sondern weil mich bei Pascal nach der Anfangszeit die Restriktivität 
der Sprache zunehmend genervt hat. Die ist gut für Leute, die nicht 
wissen, was sie tun und deswegen die Grenzen unabsichtlich und 
irrtümlich überschreiten. Deswegen ist es eine gute Lehrsprache. 
Jenseits davon wird diese Philosophie zum Ärgernis.

Ich möchte nicht dauernd den Compiler bekämpfen müssen, sondern ich 
will, daß der Compiler das umsetzt, was ich sage, Punkt. C gibt mir 
genau diese Grundeinstellung.

> 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

Falsch, C99 beispielsweise hat auch portable Datentypen eingeführt. Gut, 
Du hast ja schon vorgeführt, daß Du nicht siehst, was eigentlich der 
Punkt an uint32_t ist. Über die fast-Datentypen muß man dann wohl nicht 
mehr reden.

> Und nun guck dir Pascal in seiner heutigen Form (FPC oder Embarcadero)
> an. Merkst du da was?

Ja, besonders bei Embarcadero merke ich, daß ich mich nie auf eine 
proprietäre Sprache verlassen würde, die unter der Fuchtel einer Firma 
steht. Besonders dann nicht, wenn es dieser Firma nicht besonders gut 
geht.

Daß der spanische Entwicklungsstandort mit 80 Leuten dichtgemacht wurde 
dieses Jahr, weißt Du so gut wie ich.

> Pascal ist zukunftsfähig, C nicht.

Pascal hat seine Zukunft bereits hinter sich.

> Oder anders herum: Du magst C mehr als Pascal, aber kann C deshalb
> Objektorientiertheit?

In dem Bereich, wo C sinnvoll eingesetzt wird, brauche ich den OOP-Krams 
nicht. OOP ist sinnvoll für Simulationen (zu denen auch entsprechende 
Spiele zählen) und GUIs. Sonst ist OOP schlichtweg fehl am Platze.

Exceptions brauche ich nicht, weil ich von vornherein Fehlerfälle nicht 
zulasse. Sowas läuft bei mir unter vernünftigem Design, daß man das 
abfängt.

Strings gehen in C als C-Strings tadellos. Man kann sogar Pascalstrings 
nachbilden, falls man das wollen sollte. Natürlich gibt die Sprache das 
her.

Nur, insofern gebe ich Dir recht, ich würde in C nicht GUIs 
programmieren wollen. Ich habe das nämlich getan und WEISS, wie das ist 
- echt nicht schön. Massiv parallele Architekturen wären auch kein 
Anwendungsfall für C, und auch nicht für C++, und auch nicht für OOP 
generell.

C ist als lowlevel-Sprache positioniert, für Systemprogrammierung, und 
dafür ist dieser portable Makroassembler einfach super, IMO.

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


Lesenswert?

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

Weißt du, wenn die Leute hätten für alles überall vorzugsweise
Pascal nehmen wollen, dann wäre die Sprache ja da gewesen.  Sie
ist einigermaßen genauso alt wie C, beide standen durchaus in einer
gewissen Konkurrenz.

Wenn nun 40 Jahre später Pascal eher ein Rand-Dasein führt, dann
kannst du natürlich vortrefflich auf C herumhacken, was man dort
hätte alles anders und besser machen sollen (bis es am Ende auch
nur ein anderes Pascal wäre).  Trotzdem macht die Welt eben in
erster Linie C, und nein, das liegt nicht nur an der Verfügbarkeit
von Compilern.  Pascal-Compiler gab's auch schon lange, auch günstig
(wie Turbo-Pascal) oder kostenlos (GNU).  Es muss also irgendwas
anderes sein, warum es eben doch das ach so schröckliche, mit
Geburtsfehlern noch und nöcher versehene C ist, was heutzutage
allgegenwärtig ist.

Ich habe übrigens auch viel in Pascal programmiert und fand das
keineswegs schlecht.

von Zeno (Gast)


Lesenswert?

Paul B. schrieb:
> Zeiger? Die könnten beim Schreiben eines Uhrenprogrammes nützlich sein.
>
> O.T.
>
> Eigentlich gehört doch hier ein Zaun drum mit Warnschildern:
>
> "Achtung! C-Fetischisten
>
> Nicht füttern oder tränken!
>
> Insassen werfen mit Operatoren um sich!"

Geiler Post!

ER hat nicht ganz unrecht.

von Zeno (Gast)


Lesenswert?

Christopher C. schrieb:
> außer der Syntax sehr wenig mit
> C gemein

Das reicht schon!

von (prx) A. K. (prx)


Lesenswert?

Paul B. schrieb:
> "Achtung! C-Fetischisten

Bisschen sehr bemüht, der Witz. Es geht hier in den besseren Teilen auch 
darum, über C oder Sprachen generell zu diskutieren, gerade ohne sich 
gegenseitig Fetischismus oder Fanatismus vorzuwerfen, bloss weil man sie 
kennt und nutzt. Und umgekehrt auch darum, nicht jene in Bausch und 
Bogen zu verdammen, bloss weil sie sie kritisieren.

Der Vorwurf von Fetischismus erhöht nur die Aggression.

von Zeno (Gast)


Lesenswert?

Nop schrieb:
> In dem Bereich, wo C sinnvoll eingesetzt wird, brauche ich den OOP-Krams
> nicht. OOP ist sinnvoll für Simulationen (zu denen auch entsprechende
> Spiele zählen) und GUIs. Sonst ist OOP schlichtweg fehl am Platze.

Du hast den Sinn von OOP nicht verstanden.

Nop schrieb:
> Exceptions brauche ich nicht, weil ich von vornherein Fehlerfälle nicht
> zulasse. Sowas läuft bei mir unter vernünftigem Design, daß man das
> abfängt.

So viel Überheblichkeit muß man erst mal drauf haben. Da würde sogar der 
Schöpfer von C erblassen


Zeno

von Stefan F. (Gast)


Lesenswert?

In einem der K&R Bücher schreiben die Autoren selbst, dass sie mit dem 
langfristigen Erfolg der Sprache gar nicht gerechnet hatten.

Bei der Entwicklung hatten sie nicht darüber nachgedacht, welche 
Bedürfnisse die Programmierer 40 Jahre später haben würden - auf 
Maschinen, die 10000 mal so Leistungsstark wären. Damals hatte man über 
Internet, Video-Player, 3D Kriegsspiele und Virtual Reality 
verständlicherweise noch nicht so viel nachgedacht.

von Ralf D. (doeblitz)


Lesenswert?

Zeno schrieb:
> Nop schrieb:
>> Und mal ehrlich, Wirths Schöpfungen mögen akademisch ja toll
>> sein, sind aber praktisch weitgehend geflopt. C nicht.
[...]
> Ach und meinst Du Embacadero (ehemals Borland) würde immer noch
> Pascalcompiler bauen und zu horrenten Preisen anbieten, wenn es dafür
> keinen Markt gäbe?

Borland Pascal verhält sich zu Wirths Pascal ungefähr so wie C++ zu C. 
Mit der Wirthschen Urversion ließ sich wirklich nur akademischer Kram 
verbrechen, für die praktische Nutzung waren die diversen Erweiterungen 
von Turbo Pascal einfach notwendig (jedenfalls wenn man mehr als 
Batchverarbeitung oder Interaktion a la dumb TTY machen wollte).

von Nop (Gast)


Lesenswert?

Zeno schrieb:

> Du hast den Sinn von OOP nicht verstanden.

Nein, ich habe nur hinter den OOP-Hype der 90er gesehen, als OOP als 
silver bullet für alles inklusive Fußpilz angepriesen wurde.

> So viel Überheblichkeit muß man erst mal drauf haben.

Wenn Du Deine System nicht robust designen willst, ist das ja nun nicht 
mein Problem. Tatsächlich ist das Berücksichtigen von Fehlerfällen und 
Randfällen 90% von robustem Systemdesign.

von Zeno (Gast)


Lesenswert?

Nop schrieb:
> Wenn Du Deine System nicht robust designen willst, ist das ja nun nicht
> mein Problem. Tatsächlich ist das Berücksichtigen von Fehlerfällen und
> Randfällen 90% von robustem Systemdesign.

Natürlich möchte jeder, daß seine Software stabil läuft und genau aus 
diesem Grund wird Software so geschrieben, daß möglichst alle Fehler 
abgefangen werden. Ich kann aber nicht alle Fehler im voraus erfassen.
Beispiel:
Ich möchte mit meinem Programm Messwerte einlesen und diese weiter 
verarbeiten. Dabei wird mit diesen Werten gerechnet und u.a. auch eine 
Division durch geführt. Dumm bloß wenn dabei ein Wert zufällig 0 ist 
oder noch blööder bei der Berechnung ergibt sich ein Wert der 0 ist und 
mit dem muß weiter gerechnet werden. Man könnte das z.B. mit if abfangen 
und so die Berechnung bei 0 überspringen. Wenig elegant! Ich kapsle die 
Berechnung, bei Pascal, in einem try except oder auch try finally Block, 
je nachdem was ich erreichen möchte. Ich kann so auf solche Fehler 
reagieren. In diesem Sinne sind Exceptions ein Segen.
Sie sind schlichtweg eine Hilfe, aber sie dienen definitiv nicht dazu 
schlampig zu programmieren.

Exceptions machen durchaus Sinn und können das Leben erheblich 
vereinfachen. Gerade wenn man Programme mit viel Userinteraktion 
schreibt kommt man fasst nicht mehr an Exceptions vorbei um zu 
verhindern, daß das Programm durch Fehleingaben ständig abstürzt, es sei 
denn man möchte die Schmerzgrenze der User austesten.

Zeno

Zeno

von (prx) A. K. (prx)


Lesenswert?

Exceptions können auch die Les- und Wartbarkeit von Programmen 
verbessern. Wenn auf jede produktive Zeile 20 Zeilen Fehlerbehandlung 
kommen, dann sieht man den Wald vor lauter Bäumen nicht mehr.

von Nop (Gast)


Lesenswert?

Zeno schrieb:

> Ich kann aber nicht alle Fehler im voraus erfassen.

Das ist die Kunst im Systemdesign. Ich habe zeitweise die Entwicklung 
bewußt für einige Jahre verlassen und stattdessen im Testfeld 
gearbeitet. Die Rechtfertigung, wieso die jeweilige Firma einen für 
sowas überhaupt bezahlt, ist die, daß man Fehler findet, bevor der Kunde 
auf sie trifft und mault.

Das gibt einem definitiv eine völlig andere Denkweise. Entwickler 
wollen, daß ihr System funktioniert. Tester wollen zeigen, daß es das 
nicht tut. Rate mal, wie sich solche Erfahrung dann aufs Systemdesign 
auswirkt.

> Beispiel:
> Ich möchte mit meinem Programm Messwerte einlesen und diese weiter
> verarbeiten. Dabei wird mit diesen Werten gerechnet und u.a. auch eine
> Division durch geführt.

Also komm, wenn ein Algorithmus Divisionen mit Meßwerten macht, dann ist 
es vollkommen offensichtlich, daß man sich Gedanken machen muß, was bei 
null herauskommt - und sei es, daß die Null durch einen Kabelbruch 
zustandekommt, dessentwegen irgendein Pulldown die Spannung auf GND 
zieht.

> Man könnte das z.B. mit if abfangen
> und so die Berechnung bei 0 überspringen. Wenig elegant! Ich kapsle die
> Berechnung, bei Pascal, in einem try except oder auch try finally Block,
> je nachdem was ich erreichen möchte.

Siehste, und ich mache mir Gedanken, wieso da eine Null ist, wo keine 
sein dürfte - und erwäge irgendeine Art von hilfreicher Fehlernachricht, 
weil offenbar irgendwas mit dem System nicht stimmt. Statt eine 
Exception vorzuschieben, sehe ich validity-Bits für die Ausgangsdaten 
vor.

> Gerade wenn man Programme mit viel Userinteraktion
> schreibt kommt man fasst nicht mehr an Exceptions vorbei um zu
> verhindern, daß das Programm durch Fehleingaben ständig abstürzt

Ja, wenn man schlampig programmiert und die Eingabedaten nicht 
validiert, dann schon. Ich rechne beim Systemdesign allerdings von 
vornherein damit, daß das System von allen Seiten mit ungültigen Daten 
aller Art bombardiert wird, und erwäge, welche Teile des Systems dann 
eigentlich noch funktional sein können und welche nicht. Dadurch 
erreiche ich, daß die Dinge, die dennoch funktionieren sollten, das auch 
tun.

Ich designe auch Module so, daß sie sich selbst prüfen, selbst wenn ich 
weiß, daß diese Checks aufgrund des Gesamtdesigns nie zuschlagen 
dürften. Aber halt rein, falls sich später mal das Interfacing ändern 
sollte.

Weil ich meine Denkarbeit nicht an Compiler abgebe. Deswegen 
funktionieren meine Systeme auch unter ungünstigen Umständen noch 
soweit, wie es systembedingt eben möglich ist. Mit Fallbackmodi aller 
Art.

Ich habe derlei nicht programmiert, aber vielleicht ist Dir der 
Qantas-Unfall eines A380 ein Begriff. Bei dem Flug ist ein Triebwerk 
explodiert, und die Trümmerteile haben diverse Energieleitungen, 
Datenleitungen und Hydraulikleitungen des Flugzeugs zerrissen. Das war 
Qantas Flight 32, wenn Du googeln möchtest.

Das Wunder ist, daß die Kiste zwar vollkommen in den Seilen hing, 
hunderte von Fehlermeldungen, und außer den guten Entwicklern war es 
auch der brillante Kapitän. Aber Tatsache ist, der Flieger ist selbst 
dermaßen angeschlagen heil runtergekommen OHNE Personenschäden.

DAS nenne ich ein Systemdesign. Selbst wenn man nicht so kritische 
Systeme programmiert, aber SOWAS sind meine Vorbilder.

von (prx) A. K. (prx)


Lesenswert?

Nop schrieb:
> DAS nenne ich ein Systemdesign.

... und eine grosse Portion Glück.

Das Systemdesign war beispielsweise in einem Punkt so bescheiden, dass 
der Vogel wohl wegen Spritmangel runtergefallen wäre bevor sie die 
letzte der Meldungen lesen konnten, wenn es einen Tank erwischt hätte. 
Haben sie daraufhin geändert, damit die Piloten in solchen Fällen nicht 
in Meldungen ersaufen.

: Bearbeitet durch User
von Nop (Gast)


Lesenswert?

A. K. schrieb:

> der Vogel wohl wegen Spritmangel runtergefallen wäre

Das wäre er nicht, denn außer bei Start und Landung kann so ein Flieger 
selbst völlig ohne Sprit noch hunderte Kilometer segeln. Für die 
Elektronik klappt dann eine Windturbine aus, die aus dem Fahrtwind Strom 
erzeugt.

Im Übrigen war eines der Hauptprobleme dabei, daß der Flieger wesentlich 
ZUVIEL Sprit hatte, weswegen der noch stundenlang erstmal rumgeflogen 
ist, um ausreichend Sprint zu verbrennen, so daß die Landung möglich 
wurde.

von Nop (Gast)


Lesenswert?

A. K. schrieb im Beitrag #4758902:
> Aber das geht nun etwas vom Thema weg. Wenn man mal davon absieht, dass
> es nie möglich sein wird, alle Eventualitäten vorher einzurechnen.

Naja, aber Fakt ist, das hat funktioniert, was ich schon echt 
bemerkenswert finde. Die meisten von uns hier werden nie dermaßen 
anspruchsvolle Systeme entwerfen, aber ein Vorbild ist sowas dennoch.

Nur, wenn ich schon lese, daß man Exceptions deswegen "braucht", weil 
man zu faul ist, Eingabedaten zu validieren, dann krieg ich doch nen 
Föhn. Das System wird auch mit Exceptions ein ziemlicher Mott werden.

von (prx) A. K. (prx)


Lesenswert?

Nop schrieb:
> Nur, wenn ich schon lese, daß man Exceptions deswegen "braucht", weil
> man zu faul ist, Eingabedaten zu validieren, dann krieg ich doch nen
> Föhn. Das System wird auch mit Exceptions ein ziemlicher Mott werden.

Yep. Das muss in die Hose gehen. Wird eher a posteriori interessant. 
Also beispielsweise ob du jeden verdammten Aufruf von irgendwas einzeln 
auf alle Fehlerwerte abklapperst und behandelst, oder ob das summarisch 
im Exception-Teil endet.

von Nop (Gast)


Lesenswert?

A. K. schrieb:
> Also beispielsweise ob du jeden verdammten Aufruf von irgendwas einzeln
> auf alle Fehlerwerte abklapperst und behandelst, oder ob das summarisch
> im Exception-Teil endet.

Ja, und ein System, das am Ende nur weiß "irgendwas ist verkehrt", kann 
darauf dann auch nicht mehr differenziert reagieren. Das wäre ja noch 
irgendwo tolerierbar als allerletzter Fallback-Fall, aber offensichtlich 
verführt eine Programmiersprache mit solchen Features dann stattdessen 
zu schlampiger Fehlerbehandlung. Einfacher zu programmieren, weil man 
nicht  nachdenken braucht, aber das Ergebnis ist eben schlechter.

Wenn ich solche schlampigen Ergebnisse aber weder will noch brauche, 
dann brauche ich auch keine Sprache mit solchen Features.

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

W.S. schrieb:
> es kann alles, was C kann

Seit wann kennt Pascal variadische Funktionen? Das wäre ja mal was 
neues.

von (prx) A. K. (prx)


Lesenswert?

Nop schrieb:
> Ja, und ein System, das am Ende nur weiß "irgendwas ist verkehrt", kann
> darauf dann auch nicht mehr differenziert reagieren.

Exceptions bedeuten nicht, dass jede Information über deren Ursache 
verloren ginge. Und es geht dabei auch nicht um /0 oder Index-Overflow, 
sondern bietet eine Alternative zu beispielsweise durch Layer 
durchgereichten Error-Returns. Das ist natürlich kein Allheilmittel für 
alle Lebenslagen und kann seinerseits auch wiederum irritieren.

Fehlerbehandlung in klassischer Prozeduraler Programmierung kann den 
produktiven Code mittendrin ziemlich verwässern, so dass man ihn kaum 
noch wiederfindet. Exception-Handling kann das aufdröseln, indem der 
produktive Code relativ dicht steht und damit am Stück verständlich 
wird, während die Fehlerhandhabung ebenso konzentriert an anderer Stelle 
steht.

: Bearbeitet durch User
von Yalu X. (yalu) (Moderator)


Lesenswert?

Nop schrieb:
> Nur, wenn ich schon lese, daß man Exceptions deswegen "braucht", weil
> man zu faul ist, Eingabedaten zu validieren, dann krieg ich doch nen
> Föhn.

Du hast möglicherweise nicht ganz verstanden, was Exceptions sind und
wie sie eingesetzt werden.

Sie ersetzen keineswegs die Prüfung von Eingabedaten, sondern stellen
einen Mechanismus bereit, die durch die Prüfung erkannten Fehlerfälle
auf unkomplizierte Weise an den Programmteil zu transferieren, der die
Reaktion darauf implementiert.

Wenn bspw. auf hardwarenaher Ebene bei der Abfrage UART-Statusregisters
festgestellt wird, dass ein Byte fehlerhaft übertragen worden ist, muss
dieser Fehlerstatus oft über viele Unterprogrammebenen an das
Hauptprogramm oder ein in der Hierarchie höherliegendes Unterprogramm
hochgereicht werden, das seinerseits eine andere Routine aufruft, die
eine entsrpechende Aktion ausführt (im einfachsten Fall bspw. eine
Fehlermeldung auf dem Bildschirm ausgibt).

Der klassische Weg verwendet dabei Fehlercodes, die als Funktionswert
der jeweiligen Unterprogramme an die jeweils nächsthöhere Ebene
zurückgegeben werden. Diese Methode hat aber den Nachteil, dass jedes
dieser Unterprogramme abfragen muss, ob der Aufruf des jeweils
nächsttieferen Unterprogramms erfolgreich verlief. Man braucht also
nicht nur eine Fehlerabfrage an der eigentlichen Fehlerquelle, sondern
ganz viele (jeweils eine pro Unterprogrammebene).

Mit Exceptions reduziert sich der ganze Aufwand auf die eigentliche
Abfrage des UART-Registers, das Auslösen der Exception bei erkanntem
Fehler und das Abfangen des Fehlers auf der Unterprogrammebene, wo auch
die Reaktion auf den Fehler ausgelöst wird. Alle Unterprogramme, die in
der Hierarchie dazwischen liegen, bleiben von der Fehlerbehandlung
völlig unberührt. Fehlerbehandlungscode gibt es also nur dort, wo der
Fehler entsteht und dort, wo er behandelt wird, sonst nirgends. Das
erhöht die Übersicht und die Erweiterbarkeit des Programms beträchtlich.

von (prx) A. K. (prx)


Lesenswert?

Rufus Τ. F. schrieb:
> Seit wann kennt Pascal variadische Funktionen? Das wäre ja mal was
> neues.

Ich denke, das war eher im Gesamtbild gemeint. Nicht bezogen auf 
zeilenweise identische Umsetzung.

Braucht man das unbedingt?

von Zeno (Gast)


Lesenswert?

Nop schrieb:
> Siehste, und ich mache mir Gedanken, wieso da eine Null ist, wo keine
> sein dürfte - und erwäge irgendeine Art von hilfreicher Fehlernachricht,
> weil offenbar irgendwas mit dem System nicht stimmt. Statt eine
> Exception vorzuschieben, sehe ich validity-Bits für die Ausgangsdaten
> vor.

Oh da sieht man das Du von der Praxis halt weit entfernt bist. Messwerte 
mit Null sind durchaus möglich und auch kein Fehler. Wenn ich zum 
Beispiel eine Messmaschine kalibriere, dann nehme ich Längennormal und 
messe dieses mehrmals mit der Maschine aus. Dabei interessiert mich 
nicht die absolut gemessene Länge, sondern für mich ist die Differenz 
zwischen dem Nominalwert (also der kalibrierten Länge des Normals) und 
dem Messwert interessant und diese kann durchaus auch Null sein. Mit 
diesen Werten werden jetzt diverse Berechnungen durchgeführt und da ist 
es schon möglich das mathematisch nicht definierte Berechnungen daraus 
resultieren, wie z.B. Divisionen durch Null. Die Messwerte werden 
automatisch erzeugt und auch die Auswertung läuft weitestgehend 
automatisch ab. Da kann ich nicht darauf vertrauen das da nur korrekte 
Werte vorkommen. Für diesen Anwendungsfall sind Exceptions ein Segen. 
Als ich die Vorgängersoftware programmiert habe gab es noch kein 
Exceptionhandling und man mußte selbst dafür sorgen so was abzufangen, 
was in aller Regel nicht zu 100% gelingt. Selbst wenn man die heute 
verfügbare Unittest bemühen würde kann man nicht alle Fehler 
voraussehen, denn auch der Unittest muß man sagen was sie prüfen soll. 
Erkennt man eine Konstellation nicht dann wird dieser Fall auch nicht 
abgeprüft.

Ich (muß) arbeite mit einem Kollegen zusammen der genauso wie Du meint 
das Programmieren erfunden zu haben. Er läßt sich nichts sagen und meint 
alles im Griff zu haben. Er versucht sich seit 2 Jahren daran mein 
Programm nachzuprogrammieren - bisher mit mäßigen Erfolg. Unittest ist 
erfolgreich durchgelaufen, aber leider sind die Testfälle als auch das 
aktuelle Programm soweit an der Realität vorbei, daß an einen 
produktiven Einsatz noch lange nicht zu denken ist.

Du glaubst ernsthaft, daß Du unfehlbar bist? Träum weiter.


Zeno

von Nop (Gast)


Lesenswert?

A. K. schrieb:
> Fehlerbehandlung in klassischer Prozeduraler Programmierung kann den
> produktiven Code mittendrin ziemlich verwässern

Wenn man es verkehrt macht, vielleicht. Nicht aber, wenn man eine klare 
Aufteilung hat, die da lautet "erst Validierung, dann Algorithmus".

von Nop (Gast)


Lesenswert?

Yalu X. schrieb:
> Man braucht also
> nicht nur eine Fehlerabfrage an der eigentlichen Fehlerquelle, sondern
> ganz viele (jeweils eine pro Unterprogrammebene).

Das aber auch nur dann, wenn der Sinn der ganzen Aktion letztlich der 
ist, die Entscheidung an den Nutzer abzuwälzen. Auf 
Microcontroller-Systemen GIBT es aber keinen "Nutzer", fertig. Das 
System muß selber zusehen, wie es mit der Situation klarkommt. Es hängt 
irgendwo da draußen, ist auf sich gestellt, und niemand wird kommen, um 
es zu betüddeln und irgendwas zu "klicken".

Von daher halte ich den ganzen Ansatz schon für verkehrt. Die unterste 
Schicht soll dann eben den Fehler feststellen und schlicht dafür sorgen, 
daß auf höherer Ebene ein Protokollfehler entsteht, der dann letztlich 
zu einem Re-Transmit führt.

Ooops.. dazu müssen die Pakete/Nachrichten/whatever auch Checksummen 
haben? NEIN! DOCH! OHHH! (;

von (prx) A. K. (prx)


Lesenswert?

Nop schrieb:
> Wenn man es verkehrt macht, vielleicht. Nicht aber, wenn man eine klare
> Aufteilung hat, die da lautet "erst Validierung, dann Algorithmus".

Egal wie oft du Inputs validierst: Ob es das Item überhaupt gibt, dessen 
Kennzeichnung übergeben wird, weisst du erst, wenn du danach fragst. Ist 
ein Fehlschlag selten und unerwartet, dann kann es wesentlich 
übersichtlicher sein, auf einem recht hohen Layer damit umzugehen, als 
den Erfolg in allen Layern zwischendrin jedesmal abzufragen.

: Bearbeitet durch User
von Nop (Gast)


Lesenswert?

Zeno schrieb:

> Oh da sieht man das Du von der Praxis halt weit entfernt bist.

Im Gegenteil, offensichtlich habe ich davon wesentlich mehr als Du.

> Messwerte
> mit Null sind durchaus möglich und auch kein Fehler.

Wenn es ein Meßwert ist, durch den per Design zu dividieren ist, dann 
IST ein Meßwert null ein Fehlerzustand. Wenn Du das anders siehst, wirf 
mir nicht fehlende Praxis dafür vor.

> Beispiel eine Messmaschine kalibriere, dann nehme ich Längennormal und
> messe dieses mehrmals mit der Maschine aus. Dabei interessiert mich
> nicht die absolut gemessene Länge, sondern für mich ist die Differenz
> zwischen dem Nominalwert (also der kalibrierten Länge des Normals) und
> dem Messwert interessant und diese kann durchaus auch Null sein.

Ach. Jetzt erklär mir nur noch, in welchem Falle Du dann durch diese 
Differenz zu dividieren gedenkst - wo bei so einem Design es gerade der 
Idealzustand ist, daß die Differenz null ist!

> Mit
> diesen Werten werden jetzt diverse Berechnungen durchgeführt und da ist
> es schon möglich das mathematisch nicht definierte Berechnungen daraus
> resultieren, wie z.B. Divisionen durch Null.

Das ist nicht möglich, sondern das ist grobe Schlamperei.

> Für diesen Anwendungsfall sind Exceptions ein Segen.

Sage ich ja. Du delegierst die Konsequenzen Deiner Schlamperei an die 
Programmiersprache und wunderst Dich, wieso ich derlei nicht brauche. 
Vielleicht, weil ich etwas mehr Praxis habe und mir deswegen gerade die 
Gedanken mache, die Du lieber verweigerst und an den Compiler 
delegierst.

> Du glaubst ernsthaft, daß Du unfehlbar bist?

Wenn ich einen mathematischen Algorithmus habe, dann bin ich auch in der 
Lage, den Gültigkeitsbereich der Parameter zu bestimmen. Dafür hatte ich 
einige Semester Mathe an der Uni.

Sollte der mathematische Algorithmus so komplex sein, daß ich dazu nicht 
in der Lage bin, dann ist meine Konsequenz nicht, meine Inkompetenz an 
den Compiler zu delegieren, sondern dann frage ich einen Mathematiker. 
Dafür gibt es solche Leute. Ich bin jedenfalls gut genug in Mathe, um zu 
begreifen, ab wo ich den Überblick verliere, und ich weiß auch, was dann 
zu tun ist. Nicht rumpfuschen, sondern Experten befragen.

von Zeno (Gast)


Lesenswert?

A. K. schrieb:
> Exceptions bedeuten nicht, dass jede Information über deren Ursache
> verloren ginge. Und es geht dabei auch nicht um /0 oder Index-Overflow,

Bei einer Exception geht auch nichts verloren, da hast Du völlig recht. 
Man bei der Behandlung der Exception schon abfragen warum diese 
aufgetreten ist.
Aber man kann z.B. auch, um mal bei meinem Beispiel zu bleiben, einen 
Defaultwert setzen wenn die Berechnung schief geht, oder den Messwert 
von einer weiteren Verarbeitung ausschließen. Es kommt halt immer darauf 
an was man bezwecken möchte. Eine allgemeingültige Empfehlung kann es da 
nicht geben.

Ja und es ist auch eine gute Sache, daß man Exceptions durchreichen und 
an zentraler Stelle verarbeiten kann.


Yalu X. schrieb:
> Du hast möglicherweise nicht ganz verstanden, was Exceptions sind und
> wie sie eingesetzt werden.

Ich denke mal Du hast es erfasst. Aber er programmiert mit C und da gibt 
es keine Exceptions, also muß er das Fehlen selbiger schön reden.

Zeno

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


Lesenswert?

A. K. schrieb:

(Variadische Funktionen)

> Braucht man das unbedingt?

Selbst Pascal braucht sie (write[ln], read[ln]).

von Zeno (Gast)


Lesenswert?

Nop schrieb:
> A. K. schrieb:
>> Fehlerbehandlung in klassischer Prozeduraler Programmierung kann den
>> produktiven Code mittendrin ziemlich verwässern
>
> Wenn man es verkehrt macht, vielleicht. Nicht aber, wenn man eine klare
> Aufteilung hat, die da lautet "erst Validierung, dann Algorithmus".

@A.K.
Du solltest NOP huldigen - er ist gottgleich und Du wirst ihn nicht von 
den Vorteilen eines überlegt eingesetzten Exceptionhandlings überzeugen 
können. Er kann es auch gar nicht richtig einschätzen, da er in seiner 
C-Welt lebt und unfähig ist über den Tellerrand zu schauen. Er setzt 
Exceptions und deren Handling mit Faulheit gleich und erkennt nicht das 
selbiges richtig eingesetzt ein mächtiges Werkzeug ist.
Er hängt bei K&R fest und hat einfach verpasst, daß sich die 
Programmierwelt weiter entwickelt hat und alle modernen 
Programmiersprachen Exceptions unterstützen. Selbst bei den alten 
Programmiersprachen, wie z.B. auch Pascal, hat man die Mächtigkeit von 
Exceptions erkannt und diese in den Sprachumfang aufgenommen

W.S. hat es schon richtig erkannt als er in seinem Post schrieb :
W.S. schrieb:
> Ja, C ist tatsächlich veraltet ...


Zeno

von (prx) A. K. (prx)


Lesenswert?

Jörg W. schrieb:
> (Variadische Funktionen)
>
>> Braucht man das unbedingt?
>
> Selbst Pascal braucht sie (write[ln], read[ln]).

Modula nicht mehr. Wirth war lernfähig.

von Nop (Gast)


Lesenswert?

Zeno schrieb:
> Er kann es auch gar nicht richtig einschätzen, da er in seiner
> C-Welt lebt und unfähig ist über den Tellerrand zu schauen.

Das verstehst Du falsch. Ein vernünftiges Design hat nichts mit einer 
Programmiersprache zu tun. Es ist nur so, daß Du versuchst, Deine 
Designschwächen mit Programmiersprachen zu kaschieren, weswegen Du 
solche brauchst, die das unterstützen. Ich brauche das nicht und 
vermisse das daher auch nicht.

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


Lesenswert?

A. K. schrieb:

>> Selbst Pascal braucht sie (write[ln], read[ln]).
>
> Modula nicht mehr. Wirth war lernfähig.

Allerdings mit einem Rückschritt in der Benutzerfreundlichkeit.
1
   WriteString("foo bar ist ");
2
   WriteInt(foobar, 2);
3
   WriteString(" Äppelstücken");
4
   WriteLn;

vs.
1
   WriteLn('foo bar ist ', foobar, ' Äppelstücken');

(vs.
1
printf("foo bar ist %d Äppelstücken\n", foobar);
 :)

von (prx) A. K. (prx)


Lesenswert?

Jörg W. schrieb:
> Selbst Pascal braucht sie (write[ln], read[ln]).

Apropos: Wie sieht die Deklaration einer dieser Funktionen aus, wenn in 
Pascal selbst geschrieben?

von Nop (Gast)


Lesenswert?

.. und nebenbei bemerkt, von jemandem, der im Thread bewiesen hat, daß 
er von C gar keine Ahnung hat, einen C-Tellerrand vorgeworfen zu 
bekommen, ist schon drollig. Bilde Du Dich erstmal soweit fort, daß Du 
diesen Tellerrand erreichst, dann reden wir weiter.

von Yalu X. (yalu) (Moderator)


Lesenswert?

Nop schrieb:
> Yalu X. schrieb:
>> Man braucht also
>> nicht nur eine Fehlerabfrage an der eigentlichen Fehlerquelle, sondern
>> ganz viele (jeweils eine pro Unterprogrammebene).
>
> Das aber auch nur dann, wenn der Sinn der ganzen Aktion letztlich der
> ist, die Entscheidung an den Nutzer abzuwälzen. Auf
> Microcontroller-Systemen GIBT es aber keinen "Nutzer", fertig.

Das mit der Fehlermeldung auf dem Bildschirm war nur ein Beispiel:

Yalu X. schrieb:
> Wenn bspw. auf hardwarenaher Ebene bei der Abfrage UART-Statusregisters
> festgestellt wird, dass ein Byte fehlerhaft übertragen worden ist, muss
> dieser Fehlerstatus oft über viele Unterprogrammebenen an das
> Hauptprogramm oder ein in der Hierarchie höherliegendes Unterprogramm
> hochgereicht werden, das seinerseits eine andere Routine aufruft, die
> eine entsrpechende Aktion ausführt (im einfachsten Fall bspw. eine
> Fehlermeldung auf dem Bildschirm ausgibt).

Ersetze den Text in der Klammer einfach durch eine beliebige andere
Fehlerbehandlungsmethode, die dir einfällt.

Ich wollte mit dem obigen Satz nur ausdrücken, dass die Fehlerbehandlung
i.Allg. nicht im selben Unterprogramm stattfindet, in dem der Fehler
erkannt wird, sondern in einer darüberliegenden Hierarchieebene. Und
dafür erweisen sich Exceptions als sehr praktisch.

von Nop (Gast)


Lesenswert?

Yalu X. schrieb:
> Ich wollte mit dem obigen Satz nur ausdrücken, dass die Fehlerbehandlung
> i.Allg. nicht im selben Unterprogramm stattfindet, in dem der Fehler
> erkannt wird, sondern in einer darüberliegenden Hierarchieebene.

Ja, das ergibt Sinn. Nur, für einen Uart-Fehler würde ich das 
schlichtweg in einen Protokoll-Fehler rasseln lassen, den man ohnehin 
braucht, wenn der Fehler schon auf dem Draht passiert sein sollte. 
Dagegen muß man sich ohnehin absichern.

Dadurch braucht man für solche Protokoll-Sachen nicht haufenweise 
Errorcodes nach oben durchreichen. Das Ergebnis wird dann schlichtweg 
ein Re-ransmit werden, wenn die Statemachine da oben arbeitet, wie sie 
soll.

Ich habe jahrelang mit solchen Problemen in der Datenkommunikation 
gearbeitet und nie Exceptions gebraucht. Weil die Protokolle vernünftig 
designed waren, halt auf Übertragungsfehler aller Art.

Verdammt, wir haben mitunter sogar ein Handy auf die Prototypen-Platine 
gelegt und telefoniert während einer Datenübertragung.

von Zeno (Gast)


Lesenswert?

Nop schrieb:
> Das verstehst Du falsch. Ein vernünftiges Design hat nichts mit einer
> Programmiersprache zu tun. Es ist nur so, daß Du versuchst, Deine
> Designschwächen mit Programmiersprachen zu kaschieren, weswegen Du
> solche brauchst, die das unterstützen. Ich brauche das nicht und
> vermisse das daher auch nicht.

Ich brauche nichts zu kaschieren! Die von mir erstellten Programme 
werden in meiner Firma seit 15 Jahren weltweit eingesetzt. Von einigen 
Programmen wußte ich noch nicht mal, daß sie soweit verbreitet sind, da 
ich sie nur als Hilfstools für mich geschrieben habe und sie nur einem 
kleinen Kollegenkreis überlassen habe.
Ich kann also nicht wirklich viel falsch gemacht haben.

Das mal nur so nebenbei.

Ich mache bestimmt nicht so perfekte Programme wie Du, aber im Gegensatz 
zu Dir bin ich auf dem Boden der Tatsachen geblieben und erhebe mich 
nicht über andere.
Deine Arroganz ist kaum noch zu toppen. So einen Besserwisser wie Dich 
habe ich hier im Forum ja überhaupt noch nicht angetroffen.

Ich befürchte mal Dein Nickname ist nicht nur Dein Nickname sondern 
Programm und Dir muß ich den Begriff NOP bestimmt nicht erklären.


Zeno

von Nop (Gast)


Lesenswert?

Zeno schrieb:
> Ich brauche nichts zu kaschieren! Die von mir erstellten Programme
> werden in meiner Firma seit 15 Jahren weltweit eingesetzt.

Hauptsache, sie sind nicht gerade in C geschrieben.. oder gar C++. 
Wenn's in Pascal o.ä. ist, wieso nicht.

> Ich mache bestimmt nicht so perfekte Programme wie Du, aber im Gegensatz
> zu Dir bin ich auf dem Boden der Tatsachen geblieben und erhebe mich
> nicht über andere.

Doch, das tust Du, und das wurde Dir hier auch schon gesagt. Du hast 
z.B. zur Schau gestellt, daß Du keine Ahnung von C hast, aber schonmal 
Compilerfehler diagnostizierst.

> Deine Arroganz ist kaum noch zu toppen. So einen Besserwisser wie Dich
> habe ich hier im Forum ja überhaupt noch nicht angetroffen.

Kann ich auch nichts dafür, daß ich mit meinem Programmansatz nunmal 
nicht in derselben Liga spiele wie Du. Sorry, wenn Dir das ein 
Egoproblem bereitet, aber in meiner Freizeit bin ich nicht gezwungen, 
mit den Egoproblemen anderer Leute betüddelnd umzugehen.

Wenn jemand wie W.S. über C herzieht, stimme ich dem zwar auch so nicht 
zu, aber zumindest hat er auch was gerissen. Und im Gegensatz zu Dir 
weiß so jemand auch, was er kritisiert, während Du ja nichtmal 
Grundlagen dessen verstanden hast, was Du da kritisiert.

von Daniel H. (Firma: keine) (commander)


Lesenswert?

Was ein Kindergarten.

Können wir uns darauf einigen, dass Gabeln die schlechteren Harken sind 
weil man mit Schaufeln nicht so gut schneiden kann?

von Yalu X. (yalu) (Moderator)


Lesenswert?

A. K. schrieb:
> Jörg W. schrieb:
>> Selbst Pascal braucht sie (write[ln], read[ln]).
>
> Apropos: Wie sieht die Deklaration einer dieser Funktionen aus, wenn in
> Pascal selbst geschrieben?

Ganz einfach:

1
procedure Writeln(Args: Arguments);
2
3
procedure WriteLn(var F: Text; Args: Arguments);
4
5
procedure ReadLn(Args: Argument);
6
7
procedure ReadLn(var F: Text; Args: Arguments);

Hier nachzulesen:

  http://www.freepascal.org/docs-html/rtl/system/writeln.html

Bevor du aber jetzt den Quellcode von Free Pascal herunterlädst, um
nachzusehen, was "Arguments" wohl für ein Datentyp ist, hier ein
Ausschnitt aus der Datei system.fpd, auf die im obigen Link verwiesen
wird (man beachte den Kommentar am Anfang):

1
{
2
    […]
3
    This File contains extra, phony declarations used in fpdoc.
4
    […]
5
 **********************************************************************}
6
7
[…]
8
Procedure Read (Var F : Text; Args : Arguments);
9
Procedure ReadLn (Var F : Text; Args : Arguments);
10
Procedure Read (Args : Arguments);
11
Procedure ReadLn (Args : Arguments);
12
[…]
13
Procedure Write (Args : Arguments);
14
Procedure Writeln (Args : Arguments);
15
Procedure Write (Var F : Text; Args : Arguments);
16
Procedure WriteLn (Var F : Text; Args : Arguments);
17
[…]

Natürlich sind diese "Prozeduren" in Wirklichkeit gar keine und deswegen
auch nirgends als solche implementiert. Auch "Arguments" ist ein reiner
Phantasietyp, der nirgends definiert ist.

von Zeno (Gast)


Lesenswert?

Nop schrieb:
> Wenn jemand wie W.S. über C herzieht, stimme ich dem zwar auch so nicht
> zu, aber zumindest hat er auch was gerissen.

Über dieses Statement wird sich W.S. aber freuen, aber es wird ihn nicht 
vom Hocker reißen.

Und ob ich etwas gerissen habe oder nicht dürftest Du nicht beurteilen 
können, dafür kennst Du mich viel zu wenig. Aber nein ich habe es 
vergessen - Du kannst das natürlich.
Und was Du mir zugestehst oder nicht interessiert mich herzlich wenig. 
Ich kann auch ganz gut ohne Deine Statements und werde nicht mehr näher 
auf Deine Posts eingehen, da es vergeudete Zeit ist.

Zeno

von Nop (Gast)


Lesenswert?

Zeno schrieb:
> werde nicht mehr näher
> auf Deine Posts eingehen, da es vergeudete Zeit ist.

Genau. Kümmer mich mal lieber um die mehrfach auch von Anderen 
verlangten Quellennachweise für Deine Behauptung, daß in C ein 
if-Statement einen Bollean verlangt. Den Quellennachweis für Deine 
Ahnungslosigkeit hast Du ja immer noch nicht geliefert. Alternativ bilde 
Dich mal ein bißchen fort, auch gut.

von Rolf M. (rmagnus)


Lesenswert?

Yalu X. schrieb:
> Mit Exceptions reduziert sich der ganze Aufwand auf die eigentliche
> Abfrage des UART-Registers, das Auslösen der Exception bei erkanntem
> Fehler und das Abfangen des Fehlers auf der Unterprogrammebene, wo auch
> die Reaktion auf den Fehler ausgelöst wird. Alle Unterprogramme, die in
> der Hierarchie dazwischen liegen, bleiben von der Fehlerbehandlung
> völlig unberührt. Fehlerbehandlungscode gibt es also nur dort, wo der
> Fehler entsteht und dort, wo er behandelt wird, sonst nirgends. Das
> erhöht die Übersicht und die Erweiterbarkeit des Programms beträchtlich.

Ein Problem ergibt sich nur, wenn jede Ebene denkt, die nächsthöhere 
behandelt die Exception, und auf der höchsten Ebene wurde es vergessen 
bzw. kann man nichts sinnvolles mehr damit anfangen. Und das kommt 
offenbar öfter vor, denn ich erlebe es nicht so selten, dass Programme 
sich mit einer Exception beenden.

Zeno schrieb:
> Oh da sieht man das Du von der Praxis halt weit entfernt bist. Messwerte
> mit Null sind durchaus möglich und auch kein Fehler.

Das kommt drauf an. Natürlich kann eine Null ein korrekter Eingabewert 
sein. Dann ist aber der Algorithmus, der dadurch dividieren muss, 
fehlerhaft und muss überarbeitet werden. Es kann aber auch sein, dass 
die Null eigentlich nicht erlaubt ist. Dann ist sie sehr wohl ein 
Fehler, und den fängt man dann ab, bevor sie in den Algorithmus geht und 
wartet nicht, bis sie einem danach um die Ohren fliegt.

A. K. schrieb:
> Nop schrieb:
>> Wenn man es verkehrt macht, vielleicht. Nicht aber, wenn man eine klare
>> Aufteilung hat, die da lautet "erst Validierung, dann Algorithmus".
>
> Egal wie oft du Inputs validierst: Ob es das Item überhaupt gibt, dessen
> Kennzeichnung übergeben wird, weisst du erst, wenn du danach fragst. Ist
> ein Fehlschlag selten und unerwartet, dann kann es wesentlich
> übersichtlicher sein, auf einem recht hohen Layer damit umzugehen, als
> den Erfolg in allen Layern zwischendrin jedesmal abzufragen.

Für mich ist der Fehler auf unterschiedlichen Layern in der Regel auch 
unterschiedlich. Nehmen wir gerade mal die Division durch Null. Was soll 
ein höheres Layer mit der Information anfangen, dass irgendwo weiter 
unten durch Null dividiert wurde? Für das höhere Layer müßte es eher 
sowas wie z.B. ein InvalidInputData oder so sein. Ich muss also auf den 
Zwischenlayern die Exception fangen und dann eine entsprechend 
aufbereitete Exception werfen. Damit hab ich dann nichts gewonnen 
gegenüber dem Hochreichen von Fehlercodes.

A. K. schrieb:
> Jörg W. schrieb:
>> Selbst Pascal braucht sie (write[ln], read[ln]).
>
> Apropos: Wie sieht die Deklaration einer dieser Funktionen aus, wenn in
> Pascal selbst geschrieben?

War das nicht so, dass diese Funktionen in "klassischem" Pascal gar 
nicht so geschrieben werden können?
Das ist im Übrigen immer ein Zeichen für ein Fehldesign in einer 
Sprache, wenn bestimmte Sachen für den Anwender nicht möglich sind, aber 
für einzelne Teile der Sprache selbst dann trotzdem genutzt werden. Das 
ist ähnlich wie bei Java mit seiner fehlenden Operator-Überladung für 
Klassen, aber einem überladenen Operator + für die String-Klasse. Da 
werden Elemente von den Machern der Sprache offenbar für unnötig 
definiert, aber selber kommen sie nicht ohne aus. Was ist das denn für 
ein Irrsinn?

von (prx) A. K. (prx)


Lesenswert?

Rolf M. schrieb:
> War das nicht so, dass diese Funktionen in "klassischem" Pascal gar
> nicht so geschrieben werden können?

Das war der tiefere Sinn der Frage. ;-)

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Yalu X. schrieb:
> A. K. schrieb:
>> Jörg W. schrieb:
>>> Selbst Pascal braucht sie (write[ln], read[ln]).
>> Apropos: Wie sieht die Deklaration einer dieser Funktionen aus, wenn in
>> Pascal selbst geschrieben?
>
> Ganz einfach:

Du unterschlägst, daß es prinzipbedingt unmöglich ist, derartige 
Funktionen (oder meinetwegen "Prozeduren") in Pascal selbst zu 
schreiben.

von Nop (Gast)


Lesenswert?

Rolf M. schrieb:
> Das ist im Übrigen immer ein Zeichen für ein Fehldesign in einer
> Sprache, wenn bestimmte Sachen für den Anwender nicht möglich sind, aber
> für einzelne Teile der Sprache selbst dann trotzdem genutzt werden.

Jein; bei Pascal eigentlich nicht, weil Pascal als Lehrsprache gedacht 
war. Deswegen ist das Flair von "betreutem Programmieren" in dem Fall 
noch OK.

Das Problem war dann halt, daß die ganzen praktisch nötigen 
Erweiterungen proprietär reingefrickelt wurden, wodurch man diverse 
halbwegs taugliche, aber zueinander inkompatible Pascal-Dialekte hatte. 
Plattform-Portabilität war damit Essig, was einer der Gründe ist, wieso 
Pascal das Rennen nicht gemacht hat.

Was mir im reinen Wirth-Pascal gefehlt hat, ist auch freier Umgang mit 
Pointern. Pointercasting, Pointherarithmetik, Bitgepfriemel auf Pointer. 
Sonst muß man z.B. für ein schnelles memcpy/memset ja in Assembler 
gehen, während man das in C auch in der Hochsprache schreiben kann.

von Nop (Gast)


Lesenswert?

.. ach ja, und daß man nicht vorzeitig aus Schleifen rauskam in Pascal, 
weil es weder break noch continue gab, nervte auch. Break mußte man sich 
mit irgendwelchen zusätzlichen Flag-Fiddeleien emulieren, was langsamer 
und unübersichtlicher war.

Dieselbe Katastrophe bei Fehlerbehandlung, weil man kein goto hatte; 
nichtmal mehrfache returns in einer Funktion. Das Ergebnis waren riesige 
Blockverhaue mit diversem nesting.

Als Lehrsprache egal, denn wenn man sich auf die Implementation 
grundlegender Algorithmen beschränkt, braucht man auch keine 
Fehlerbehandlung. Aber in der Praxis echt nervig.

Weswegen das dann ja auch in Form diverser inkompatibler Dialekte 
reingefrickelt wurde. Mit dem Ergebnis, daß man dann zwar halbwegs 
dieselben Fehler wie in C machen konnte, nur halt ohne die Portabilität.

von nicht"Gast" (Gast)


Lesenswert?

Zeno schrieb:
> Ich brauche nichts zu kaschieren! Die von mir erstellten Programme
> werden in meiner Firma seit 15 Jahren weltweit eingesetzt. Von einigen
> Programmen wußte ich noch nicht mal, daß sie soweit verbreitet sind, da
> ich sie nur als Hilfstools für mich geschrieben habe und sie nur einem
> kleinen Kollegenkreis überlassen habe.
> Ich kann also nicht wirklich viel falsch gemacht haben.

Ja, Nivau sieht von unten her immer wie Arroganz aus, nicht war?

Das mit den ungewollt international eingesetzten Programmen, die nicht 
dafür gedacht waren, geht mir auch so und es kamen nie klagen. Dabei 
weiß ich ganz genau, daß das Schrott ist, den ich schnell zusammen 
gehackt habe. Das beweist also keinerlei Qaulität.

Also komm mal von deinem hohen Ross runter und lande wieder in der 
Realität.

von (prx) A. K. (prx)


Lesenswert?

Nop schrieb:
> Was mir im reinen Wirth-Pascal gefehlt hat, ist auch freier Umgang mit
> Pointern. Pointercasting, Pointherarithmetik, Bitgepfriemel auf Pointer.

Dir haben in Pascal also die Fehler von C gefehlt? ;-)

: Bearbeitet durch User
von Nop (Gast)


Lesenswert?

A. K. schrieb:
> Du meinst, dir haben in Pascal genau all jene Fehler gefehlt, die es in
> C gab? ;-)

Naja was heißt gefehlt - mit den proprietären Erweiterungen konnte man 
ja das Pascalmüsli mit Inline-Assembler umgehen. q:
Leider war man damit dann nicht nur im jeweiligen Pascaldialekt 
gefangen, sondern auch noch auf der CPU.

von Yalu X. (yalu) (Moderator)


Lesenswert?

Rolf M. schrieb:
> Ein Problem ergibt sich nur, wenn jede Ebene denkt, die nächsthöhere
> behandelt die Exception, und auf der höchsten Ebene wurde es vergessen
> bzw. kann man nichts sinnvolles mehr damit anfangen. Und das kommt
> offenbar öfter vor, denn ich erlebe es nicht so selten, dass Programme
> sich mit einer Exception beenden.

Stimmt, das habe ich auch schon oft erlebt. Wenn der Programmierer aber
vergisst, eine Fehlerbehandlung zu implementieren, kann man das nicht
den Exceptions anlasten. Verwendet er statt Exceptions Returncodes und
vergisst, diese an geeigneter Stelle auszuwerten, hat man das Problem
genauso, nur dass das Programm dann nicht mit einer Diagnosmeldung
abbricht.

Rolf M. schrieb:
> War das nicht so, dass diese Funktionen in "klassischem" Pascal gar
> nicht so geschrieben werden können?

Ja, aber auch in "modernem" Object-Pascal geht das m.W. nicht.

> Das ist im Übrigen immer ein Zeichen für ein Fehldesign in einer
> Sprache, wenn bestimmte Sachen für den Anwender nicht möglich sind, aber
> für einzelne Teile der Sprache selbst dann trotzdem genutzt werden.

Das ist Ansichtssache. Wenn man WriteLn nicht als Bibliotheksfunktion
(wie bspw. printf in C), sondern als Konstrukt der Sprache selber
ansieht, löst sich dieser Widerspruch auf. Selbst als variadische
Funktion wäre WriteLn nicht implementierbar, da es ja noch die durch
Doppelpunkt getrennte Formatparameter gibt, die zu einer völlig anderen
Syntax führen.

Die Philosophie, möglichst viele Sprachfeatures in Bibliotheksfunktionen
auszulagern, kam erst so richtig mit C auf. Seither ist man gewohnt (und
erwartet es sogar), dass zumindest die I/O-Funktionen komplett aus der
Bibliothek kommen.

Auch in Python gab es langezeit das Schlüsselwort print, dessen
Argumente nicht geklammert werden müssen. Mittlerweile (in Python 3) ist
print aber eine ganz normale Funktion (deren Argumente deswegen in
Klammern geschrieben werden müssen).

Yalu X. schrieb:
> A. K. schrieb:
>> Jörg W. schrieb:
>>> Selbst Pascal braucht sie (write[ln], read[ln]).
>> Apropos: Wie sieht die Deklaration einer dieser Funktionen aus, wenn in
>> Pascal selbst geschrieben?
>
> Ganz einfach:

Du unterschlägst, daß es prinzipbedingt unmöglich ist, derartige
Funktionen (oder meinetwegen "Prozeduren") in Pascal selbst zu
schreiben.

Nicht ich unterschlage das, sondern die Free-Pascal-Doku, aus der ich
diese Pseudodeklarationen kopiert habe ;-)

von mec (Gast)


Lesenswert?

Zeno schrieb:
> 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.

Genau für so lowlevel Zeug ist C gemacht worden, um nicht mit assembler 
arbeiten zu müssen, und bei kleinen controleren, oder für sehr 
Hardwarenahe Sachen ist C einfach das Beste Werkzeug, neben dem 
Assembler. Natürlich macht man sich damit die Finger schmutzig, es geht 
halt nicht alles im Elfenbeinturm, einer muss mal mit der Arbeit 
anfangen.
Oder anders gesagt, nimm deine bevorzugte Sprache und dann das 
Datenblatt der Hardware und Schreibe mal ein Programm um deinen String 
im Speicher zu Kopieren, Verknüpfen, etc. Da musst du ersteinmal 
überlegen, wie du den String im Speicher eigentlich ablegen und 
Interpretieren kannst, oder anders gesagt, was eigentlich ein String auf 
der Hardwareebene ist.

von (prx) A. K. (prx)


Lesenswert?

mec schrieb:
> Da musst du ersteinmal
> überlegen, wie du den String im Speicher eigentlich ablegen und
> Interpretieren kannst,

Weshalb? Wenn Strings primäre Sprachobjekte sind, oder Objekte im OOP, 
dann gibt es auch Methoden, um daraus Substrings oder Zeichen 
rauszufischen und zu ersetzen.

: Bearbeitet durch User
von Nop (Gast)


Lesenswert?

mec schrieb:
> Da musst du ersteinmal
> überlegen, wie du den String im Speicher eigentlich ablegen und
> Interpretieren kannst, oder anders gesagt, was eigentlich ein String auf
> der Hardwareebene ist.

Übrigens sind Pascalstrings noch kranker, als C-Strings je sein werden. 
Denn zwar gibt es einen Datentyp "string", bei Pascal. Das ist aber 
Kosmetik, der ist unter der Haube definiert als ein array of char. Und 
zwar alle in derselben Länge.

Der Grund ist, daß Pascal idiotischerweise die Länge eines Arrays als 
Teil seines Datentyps ansieht und dann mit dem strengen Typensystem die 
Sache vollends unbrauchbar macht.

Also einfach alle Strings mit maximaler Länge definieren und 
wegverstecken, damit der Nutzer das Elend nicht sieht. Wobei die 
maximale Länge natürlich 256 ist, weil das Längenbyte eben nur 8 bit 
hat. AUch so eine grandiose Idee.

Der Irrsinn mit den Arrays hat übrigens auch zur Folge, daß man keine 
generische Sortierroutine auf Arrays mit einem bestimmten Grundtyp, aber 
unterschiedlicher Längen machen kann. Ach was soll's, dann definiert man 
halt einfach immer alle Arrays in derselben Länge, nur um den Schlägen 
des Typensystems auszuweichen.

Oder, Trommelwirbel, man umgeht das mit Pointern. Moooment, war nicht 
gerade ein Hauptkritikpunkt an C das Herummachen mit Pointern? Tja, 
deswegen. Damit sowas geht.

von Jobst Q. (joquis)


Lesenswert?

Zeno schrieb:
> 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.

Hast du schon mal überlegt was ein String eigentlich ist? Als 
Zeichenfolge oder Zeichenkette wird es auf Deutsch übersetzt. Das kann 
man wieder zurückübersetzen als 'array of char'. Also genau so, wie es 
in C dargestellt wird. Und da man keine ganzen Speicherbereiche als 
Parameter übergeben kann, nimmt man dafür den Zeiger darauf.

Es gibt übrigens keine Programmiersprachen, in der Strings nicht als 
Zeiger übergeben werden. Nur ist es in anderen Sprachen oft ein Zeiger 
auf eine ganze Struktur bzw Objekt, während in der C-Konvention ein 
Zeiger auf die Anfangsadresse ausreicht. Damit wird die effektivste und 
schnellste Stringbearbeitung möglich.




> 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.

Für manche ist eben alles, was sie nicht verstehen oder nicht verstehen 
wollen "entartete" Kunst.

von Nop (Gast)


Lesenswert?

A. K. schrieb:
> Weshalb? Wenn Strings primäre Sprachobjekte sind, oder Objekte im OOP,
> dann gibt es auch Methoden, um daraus Substrings oder Zeichen
> rauszufischen und zu ersetzen.

Man muß trotzdem verstehen, wie die implementiert sind, sonst gibt es 
herbe Skalierungseffekte. Extrem beliebt in Dateimanagern aller Art, 
wenn dort nur Methoden irgendwie zusammengeleimt wurden. Funktioniert 
mit 50 Dateien in einem Verzeichnis und hängt dann stundenlang, wenn es 
mehrere tausend Dateien werden.

von (prx) A. K. (prx)


Lesenswert?

Jobst Q. schrieb:
> Damit wird die effektivste und schnellste Stringbearbeitung möglich.

Strings mit mitgeschleppter Länge sind oft schneller als die C Methode 
mit 0-Terminierung.

: Bearbeitet durch User
von temp (Gast)


Lesenswert?

W.S. schrieb:
> Oder anders herum: Du magst C mehr als Pascal, aber kann C deshalb
> Objektorientiertheit? Oder Exceptions? Oder Strings? nein, natürlich
> nicht.

Da kann ich nur sagen: Gott sei Dank! Ich denke mir nur mal den 
Schwachsinn aus, wenn bei jedem kleine Controller eine dynamische 
String-Unterstützung oder Exceptions im Default dabei wäre. Und das bei 
auf ein par kB begrenztem Heap. Nach 3 Tagen geht dann irgendwie nichts 
mehr nur weil der Heap fragmentiert ist...
Nein, ich und wahrscheinlich 99,9% aller embedded Entwickler wollen das 
sicher nicht, sonst würde es das geben.
Wem C nicht reicht der kann seine Quellen als C++ übersetzen und selbst 
entscheiden auf welchem Level man sich bewegt. Dann hat er auch Strings, 
Exceptions und viele andere Sachen. Aber nur wenn er will.
Ich finde die ganzen Versuche JavaScript, LUA, Pascal, Basic oder wie 
sie alle heißen auf die kleine Hardware ohne vernünftige 
Speicherverwaltung zu implementieren absoluten Käse. Bisher waren auch 
alle Versuche entweder relativ erfolglos oder hatten ein kurzes Leben.
Wenn in Zukunft selbst der kleinste Controller Mega- oder Gigabytes an 
Ram hat sieht das anders aus. Aber dann bestehen Programme die heute 
10000 Zeilen in der Summe haben aus 10Mio. Und da soll die 
Fehlerwahrscheinlichkeit kleiner sein? Und das alles nur weil man zu 
blöd ist "for(;;)" zu verstehen oder weil man bei "while(a=read())" am 
Zweifeln ist ob Fehler oder gewollt? Wenn es dann mal soweit ist, dass 
in einem einfachen digitalen Zeitrelais ein Linux-Kernel werkelt nur 
weil C etwas von Vorgestern ist, dass nur noch die senilen alten Säcke 
verwenden... , ja dann gebe ich mich geschlagen und W.S. Recht.

von temp (Gast)


Lesenswert?

A. K. schrieb:
> Strings mit mitgeschleppter Länge sind oft schneller als die C Methode
> mit 0-Terminierung

Klar wer das in dieser Form braucht kann sich in mit wenigem Aufwand 
eine kleine Lib bauen die ständige strlen() Aufrufe verhindert. Dafür 
gibt es Strukturen oder Klassen(C++). Die Länge von konstanten 
Zeichenketten im Flash weiß der Compiler selbst und kann damit arbeiten.

von Jobst Q. (joquis)


Lesenswert?

A. K. schrieb:
> Jobst Q. schrieb:
>> Damit wird die effektivste und schnellste Stringbearbeitung möglich.
>
> Strings mit mitgeschleppter Länge sind oft schneller als die C Methode
> mit 0-Terminierung.

Für einzelne Funktionen mag das stimmen, wenn es um sehr lange Strings 
geht. Dafür muss bei jeder Zuweisung oder Änderung die Länge neu 
berechnet werden. Das ist ein hoher Verwaltungsaufwand, der sich weder 
in Geschwindigkeit noch in Codegröße bezahlt macht.

In der Praxis der Stringbearbeitung, zB dem Einlesen einer 
Konfigurationsdatei, wird die Länge nur in seltenen Fällen gebraucht. 
Weder zum Überspringen von Whitespace (Leerzeichen,Tabs usw) noch zum 
Abtrennen von Kommentaren ist die Länge nützlich. Der Kommentar ist für 
das Programm nicht interessant, also brauch es auch seine Länge nicht.

Und wenn die Länge mal gebraucht wird, zB um in eine Datei zu schreiben, 
kann sie oft auch durch die vielgeschmähte Pointerarithmetik schnell 
berechnet werden.

von Nop (Gast)


Lesenswert?

Jobst Q. schrieb:
> Für einzelne Funktionen mag das stimmen, wenn es um sehr lange Strings
> geht. Dafür muss bei jeder Zuweisung oder Änderung die Länge neu
> berechnet werden.

Wirklich fies ist der Anwendungsfall, wenn man an einen C-String oftmals 
andere Strings hintendranhängen will. Wenn man das einfach mit strcat 
direkt macht, wird das lahm. Dafür ist strcat nicht gedacht.

Dann schreibt man sich eine Funktion, die nach dem Dranhängen einen 
Zeiger auf die terminierende Null zurückliefert. Der nächste String kann 
genau dort dann angehängt werden, ohne daß man den ganzen String von 
vorne bis zur Null durchloopen müßte.

von Jobst Q. (joquis)


Lesenswert?

Nop schrieb:
> Jobst Q. schrieb:
>> Für einzelne Funktionen mag das stimmen, wenn es um sehr lange Strings
>> geht. Dafür muss bei jeder Zuweisung oder Änderung die Länge neu
>> berechnet werden.
>
> Wirklich fies ist der Anwendungsfall, wenn man an einen C-String oftmals
> andere Strings hintendranhängen will. Wenn man das einfach mit strcat
> direkt macht, wird das lahm. Dafür ist strcat nicht gedacht.
>
> Dann schreibt man sich eine Funktion, die nach dem Dranhängen einen
> Zeiger auf die terminierende Null zurückliefert. Der nächste String kann
> genau dort dann angehängt werden, ohne daß man den ganzen String von
> vorne bis zur Null durchloopen müßte.

Genau so mache ich das auch mit konstruierenden Stringfunktionen. Bei 
fertigen Funktionen wie snprintf, die die Länge zurückgeben heißt es 
dann eben t+= snprintf(t,lim-t,...);

von Rolf Magnus (Gast)


Lesenswert?

Yalu X. schrieb:
>> Das ist im Übrigen immer ein Zeichen für ein Fehldesign in einer
>> Sprache, wenn bestimmte Sachen für den Anwender nicht möglich sind, aber
>> für einzelne Teile der Sprache selbst dann trotzdem genutzt werden.
>
> Das ist Ansichtssache.

Naja, wenn es da benötigt wird, dann wird es auch für Anwender sinnvoll 
sein, also ist es meines Erachtens ein Fehler, dem die selben 
Möglichkeiten zu verwehren.

> Wenn man WriteLn nicht als Bibliotheksfunktion (wie bspw. printf in C),
> sondern als Konstrukt der Sprache selber ansieht, löst sich dieser
> Widerspruch auf.

Das finde ich nicht. Im Gegenteil finde ich es unelegant, mangels 
geeignter Sprachfeatures sowas zu einem speziellen Konstrukt machen zu 
müssen, statt es auf eine Basis zu stellen, die jedem Benutzer der 
Sprache zur Verfügung steht.

> Selbst als variadische Funktion wäre WriteLn nicht implementierbar, da
> es ja noch die durch Doppelpunkt getrennte Formatparameter gibt, die zu
> einer völlig anderen Syntax führen.

Nun gut, das könnte man ja auch als Manko sehen. Noch mehr 
Sonderbehandlung, die dafür nötig ist. Nicht dass variadische 
Funktionen, wie sie in C umgesetzt sind und die Formatstring-Geschichten 
das Nonplusultra wären, aber printf lässt sich wenigstens als normale 
Funktion ohne irgendwelche Sonderlösungen implementieren.

> Die Philosophie, möglichst viele Sprachfeatures in Bibliotheksfunktionen
> auszulagern, kam erst so richtig mit C auf. Seither ist man gewohnt (und
> erwartet es sogar), dass zumindest die I/O-Funktionen komplett aus der
> Bibliothek kommen.

Ich halte das so auch für sinnvoller. Natürlich ist mir bewusst, dass 
das alles mal vor Jahrzehnten noch nicht so klar war, wie heute.

von temp (Gast)


Lesenswert?

Rolf Magnus schrieb:
> Nun gut, das könnte man ja auch als Manko sehen. Noch mehr
> Sonderbehandlung, die dafür nötig ist. Nicht dass variadische
> Funktionen, wie sie in C umgesetzt sind und die Formatstring-Geschichten
> das Nonplusultra wären, aber printf lässt sich wenigstens als normale
> Funktion ohne irgendwelche Sonderlösungen implementieren.

Und wenn man embedded unterwegs ist und sich nicht selbst um printf 
kümmert hat man entweder eine Krücke aus der newlib bei der gefühlt 80% 
der Anwender nicht wissen wo und wie sie ihren dynamischen Speicher 
herkriegt, oder es wird gemault wenn printf nicht geht. Deshalb würde 
ich printf auch nie als etwas zur Sprache C gehörendes betrachten. Es 
ist und bleibt eine Funktion aus einer Lib. Wenn mein printf keine 
double ausgeben muss, macht es auch keinen Sinn 1-2K dafür in den Flash 
zu packen. Da reicht auch eine schmale Implementierung die auf das sbrk 
ganz verzichten kann.

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


Lesenswert?

temp schrieb:
> Da reicht auch eine schmale Implementierung die auf das sbrk ganz
> verzichten kann.

Ist ja nun aber nicht so, dass es die nicht gäbe.

Ja, man könnte sich allemal technisch elegantere Lösungen wünschen,
bei denen der Linker bereits entscheiden kann, was im Hintergrund
tatsächlich an Konvertierungen benötigt wird.  Aber eins muss man
printf() & Co lassen (auch, wenn man sich dann mal Pascal's WriteLn
nach vielen Jahren wieder ansieht): aus Benutzersicht ist es ein
verdammt mächtiges und trotzdem immer noch hinreichend einfach zu
bediendendes Werkzeug, das man eigentlich selbst bei Embedded oft
genug nicht mehr missen möchte.  Die Tatsache, dass man es (dank
der v-Varianten der Funktionen) gewissermaßen auch noch ganz offiziell
„beerben“ kann (im bereits genannten Gegensatz zu Pascal), macht es
im praktischen Leben nochmal ein wenig nützlicher.

von Yalu X. (yalu) (Moderator)


Lesenswert?

Rolf Magnus schrieb:
>> Die Philosophie, möglichst viele Sprachfeatures in Bibliotheksfunktionen
>> auszulagern, kam erst so richtig mit C auf. Seither ist man gewohnt (und
>> erwartet es sogar), dass zumindest die I/O-Funktionen komplett aus der
>> Bibliothek kommen.
>
> Ich halte das so auch für sinnvoller. Natürlich ist mir bewusst, dass
> das alles mal vor Jahrzehnten noch nicht so klar war, wie heute.

Auch ich finde das nach Abwägung aller Vor- und Nachteile (etwas)
besser.

Den Hauptnachteil von printf genenüber WriteLn sehe ich darin, dass es
eine Funktion ist, die viel mehr kann als i.Allg. tatsächlich gebraucht
wird und deswegen sehr groß ist, wie auch schon von "temp" angemerkt
wurde:

temp schrieb:
> Wenn mein printf keine double ausgeben muss, macht es auch keinen Sinn
> 1-2K dafür in den Flash zu packen.

Auf PCs ist das kein Problem, auf einem AVR schon.

Bei WriteLn kann der Compiler je nach Datentyp der Argumente die jeweils
passenden Ausgaberoutinen aus der Bibliothek verwenden.

Beim GCC ist printf mittlerweile eine Built-In-Funktion und damit streng
genommen wie in Pascal ein Bestandteil der Sprache. Es gibt aber zwei
wesentliche Unterschiede:

1. Das Built-In-printf folgt nach wie vor genau der Syntax für
   Funktionsaufrufe, so dass man außer einem Geschwindigkeitsvorteil in
   manchen Fällen keinen Unterschied zum Bibliotheks-printf merkt.

2. Der GCC macht zwar kleinere Optimierungen, indem er, wo dies möglich
   ist, den printf durch einen putchar- oder puts-Aufruf ersetzt, eine
   Optimierung in Anbhängigkeit von den Argumenttypen ist aber (noch)
   nicht implementiert.

Sollte dies eines Tages geschehen, würden die Vorteile des klassischen
printf mit denen des WriteLn vereint, und es gäbe noch einen Grund
weniger, Pascal zu benutzen ;-)

Eine große Schwäche von Pascal im Zusammenhang mit WriteLn ist, dass es
keinen entsprechenden Befehl gibt, der das formatierte Ergebnis nicht
ausgibt, sondern in einen String schreibt, also das, was man in C mit
sprintf machen würde.

Die Delphi-Entwickler haben dieses Problem zwar erkannt, haben sich aber
– warum auch immer – gegen die Erweiterung von WriteLn entschieden,
obwohl dies eigentlich naheliegend gewesen wäre:
1
{ Standard-Pascal, Ausgabe auf der Konsole }
2
procedure Writeln(Args: Arguments);
3
4
{ Standard-Pascal, Ausgabe in eine Textdatei }
5
procedure WriteLn(var F: Text; Args: Arguments);
6
7
{ Erweiterung, Ausgabe in einen String }
8
procedure WriteLn(var S: String; Args: Arguments);

Stattdessen wurden die beiden neuen Bibliothekfunktionen Format und
StrFmt eingeführt:

  http://www.freepascal.org/docs-html/rtl/sysutils/format.html
  http://www.freepascal.org/docs-html/rtl/sysutils/strfmt.html

Witzigerweise entsprechen diese Funktionen einschließlich der Syntax des
Formatstrings fast genau der sprintf-Funktion in C, nur dass die
Argumente nicht direkt, sondern in einem Array variabler Länge übergeben
werden, damit die Argumentzahl konstant bleibt.

Es gibt also zwei syntaktisch völlig verschiedne Formatierungskonzepte,
deren Auswahl nicht etwa davon abhängt, was man wie formatieren möchte,
sondern lediglich davon, was man nach erfolgter Formatierung mit dem
Ergebnis tun möchte.

Das mutet schon sehr schräg an und zeigt, dass Pascal genauso wie C mit
Altlasten zu kämpfen hat, die eigentlich überholt angesehen werden, aber
aus Gründen der Kompatibilität immer noch mitgeschleppt werden müssen.

Dagegen ist es doch Pipifax, ob man nun for(;;), while(1) oder sonst
etwas für eine Endlosschleife schreibt :)

von Christopher C. (trihexagon)


Lesenswert?

C ist schon ganz nett für sehr hardwarenahes Zeug wie µC, 
Kernelentwicklung.

Aber ich tendiere immer mehr zu C++. Typsicherheit, Referenzen und 
Templates sind einfach zu praktisch. Gerade eine Möglichkeit, generische 
Datenstrukturen zu schreiben (Binäre Bäume, Verkettete Listen...), fehlt 
mir einfach in C. Es gibt ja keine Generics oder Templates in C (bitte 
keine Präprozessor Geschichten grusel). So habe ich, nachdem ich schon 
zum dritten Mal eine Verkettete Liste für meinen Kernel implementiert 
habe, entnervt aufgegeben. Werde das ganze jetzt wohl zu C++ portieren, 
damit werde ich wahrscheinlich glücklicher.

Disclaimer: Natürlich ist es prinzipiell möglich. Aber bisher habe ich 
noch keine zufriedenstellende Lösung gefunden. Die Umsetzung mit void* 
und Präprozessor ist relativ umständlich von der Bedienung. Mit C++ 
lässt sich das sehr elegant machen.

von Teo D. (teoderix)


Lesenswert?

282 Beiträge???
Habt ihr keine anderen Probleme (bzw. wichtigeres)???


EDIT: Too late

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


Lesenswert?

Nop schrieb:
> Nö, sondern weil mich bei Pascal nach der Anfangszeit die Restriktivität
> der Sprache zunehmend genervt hat.

Ähem.. ich kann das nur so verstehen, daß du zu den Leuten gehörst, die 
zu allererst int main(... hinschreiben und sich dann sagen "ach mir wird 
schon noch was einfallen". Ist das so? Gehst du denn überhaupt nicht 
planvoll an deine Arbeit? Ich schon, bei mir werden zu allererst die 
Interfaces, Typen und Daten festgelegt und ein ganzes Stück später kommt 
das Fassen in einer Programmiersprache.

Also schreib mal, was du unter Restriktivität denn überhaupt verstehst, 
daß selbige dich so genervt hat. Und wo hast du gegen den Compiler 
gekämpft?

Ich sag dir mal eins:
dein "sondern ich will, daß der Compiler das umsetzt, was ich sage, 
Punkt." ist so ziemlich das Falscheste, was man sich wünschen kann.

Du solltest dir lieber wünschen, daß der Compiler dir das umsetzt, was 
du EIGENTLICH MEINST - und nicht das, was du tatsächlich sagst (bzw. 
schreibst). Glaub's mir!


> Falsch, C99 beispielsweise hat auch portable Datentypen eingeführt.

O jemine, schon wieder dieser unselige Krempel. Da hat überhaupt keiner 
irgendwas eingeführt, sondern es war die finale Kapitulation. Und zwar 
in der Form, daß man gesagt hat "Leute macht euch für eure partikuläre 
Architektur eine Headerdatei, wo ihr reinschreibt typedef unsigned long 
uint32_t; und so weiter. Sowas haben Legionen von Leuten zuvor schon 
längst gemacht mit u32 oder anderen selbstausgedachten Namen. Jedem 
C-Compiler ist das völlig schnurz. Er kennt all dieses Zeugs nur dann, 
wenn man ihm so eine Headerdatei zuvor in den Rachen geworfen hat. Sowas 
kann jeder, du könntest dir auf diese Weise auch nop32_t oder T32NOP 
oder sonstwas kreieren. Es ist eben Mumpitz, den jeder für sich machen 
kann und es ist NICHT eine tatsächliche Sprachänderung. Kapiere das mal.


>> Pascal ist zukunftsfähig, C nicht.
> Pascal hat seine Zukunft bereits hinter sich.

Das sind mal wieder zwei verschiedene Dinge. Pascal hat die Fähigkeit, 
an zukünftige Anforderungen angepaßt zu werden. Die jüngere 
Vergangenheit hat gezeigt, daß das drin ist. Bei C war das eben an 
keiner Stelle nach ANSI mehr drin, siehe dein C99-Statement oben.

Also, hier ging es um die Renovierbarkeit der Programmiersprache - nicht 
jedoch darum, ob sie künftig genommen oder abgelehnt werden wird. Das 
sind - wie gesagt - zwei verschiedene Dinge. Ich habe durchaus den 
Eindruck, daß Pascal irgendwann verschwunden sein wird - aber eben nicht 
aufgrund etwaiger Ungeeignetheit, sondern aufgrund mentaler Ablehnung. 
Ich sagte es ja schon: die Gründe für C sehe ich vorrangig im 
außertechnischen Bereich.


> In dem Bereich, wo C sinnvoll eingesetzt wird, brauche ich den OOP-Krams
> nicht. OOP ist sinnvoll für Simulationen (zu denen auch entsprechende
> Spiele zählen) und GUIs. Sonst ist OOP schlichtweg fehl am Platze.

Sag's anders herum: Dort, wo man moderne Dinge wie GUI's benötigt - also 
überall auf allen PC's dieser Welt einschließlich aller Smartphones, 
Tablets, Navis - kann man C nicht wirklich einsetzen, denn dafür ist es 
zu poplig. Also bleibt noch die Welt der Kommandozeile, sprich 
Admi-Tätigkeit für die Server dieser Welt auf der Kommandozeile und 
Mikrocontroller ohne GUI. Ich hab mich früher genug  beim Schreiben von 
Apps für Windows-CE per EVC abgequält um mir für diese Plattformen sowas 
wie Delphi sehnlichst gewünscht gehabt zu haben.


> Exceptions brauche ich nicht, weil ich von vornherein Fehlerfälle nicht
> zulasse.

gröhl... mal im Ernst: was soll das bitte?


> Strings gehen in C als C-Strings tadellos. Man kann sogar Pascalstrings
> nachbilden, falls man das wollen sollte. Natürlich gibt die Sprache das
> her.

Jetzt übertreibst du es aber gar zu sehr. C kennt keine Strings. Punkt. 
C kennt lediglich Arrays von Zeichen und ich frag mich, ob ich dich 
überhaupt noch ernst nehmen sollte.

Anmerkung zur Effizienz: Es ist geradezu grauselig, was für einen 
unnötigen Ressourcenverbrauch das unselige Nullbyte verursacht. Man 
schaue mal in ein x-beliebiges C-Programm hinein, das mit irgendwelchem 
Text umgeht. Wie oft dort wieder und wieder jede blöde Zeichenkette nach 
diesem abgesucht wird (strlen), anstatt sich die aktuelle Länge mal auf 
intelligentere Weise zu merken, ist grauenvoll. Und das alles nur 
deshalb, weil C eben keine Strings kennt, wo man sowas auf effiziente 
Weise hätte erledigen können. Und jetzt kommen mir hier Leute mit der 
Behauptung, C sei effizient!


> C ist als lowlevel-Sprache positioniert..

Ja. Sehe ich auch so. Aber man muß es ergänzen mit "Und wo ist eine 
High-Level-Sprache, die man eben für höhere Level benutzen kann? Und die 
so nebenbei den Bereich von C auch mit abdeckt?"

Du hast unbeabsichtigt mir quasi aus dem Herzen gesprochen - teilweise.

Low Level war früher, da wurde jedes Kilobyte an RAM mit Gold 
aufgewogen.

Heutzutage braucht man was Anderes, nämlich Programmiersprachen, die:

- moderne Programmelemente (GUI) und Beherrschung größerer Datenelemente 
(Objekte und Kapselung) besser machen als C

- es dem Programmierer leicht machen und ihm so mehr Raum schaffen für 
seine eigentlichen höheren Ziele. Also ihn nicht mit 
lowlevel-Zerrigkeiten nerven, bis er sich an krude Syntax gewöhnt hat. 
Wir sind Menschen mit menschlichem Verstand und keine Maschinen - und es 
ist der falsche Weg, vom Menschen zu verlangen, daß er sich an die 
Maschine oder an krude Programmiersprachen gewöhnt. OK, sowas läßt sich 
nicht immer vermeiden, aber zmindest sollte man das nicht als Ziel aller 
Entwicklung sehen, sondern als etwas, das bei nächstbester Gelegenheit 
auszuräumen ist.

Und da kommen wir zum TO zurück, dem sowas wie
for(;;)
unverständlich ist. Ich könnte da noch was anderes dranhängen wie z.B. 
sowas:
void (*OnKey)(RCST* self, word *aKey);
oder sowas:
#define WDTC (*((volatile unsigned long *) 0xE0000004))

Wer schon länger C benutzt, wird das alles problemlos erkennen, aber 
wenn man mal wirklich ehrlich zu sich selbst ist, erkennt man an 
solchen Stellen sehr wohl, daß Formulierungen wie die obigen keine 
wirklich zukunftsträchtige gute Programmiersprache ausmachen.

W.S.

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


Lesenswert?

W.S. schrieb:
> #define WDTC (*((volatile unsigned long *) 0xE0000004))

Wie sieht denn der Zugriff auf ein Prozessor-IO-Register in
Standard-Pascal aus?

von (prx) A. K. (prx)


Lesenswert?

Schade dass hier anscheinend niemand Ada kann. Ich hatte nämlich den 
Eindruck gewonnen, dass es weit besser zu Controllern passt.

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


Lesenswert?

A. K. schrieb:
> Ich hatte nämlich den Eindruck gewonnen, dass es weit besser zu
> Controllern passt.

Ja, vermutlich schon.  Es gab ja auch mal Ansätze für eine Portierung
von GNU Ada auf den AVR, aber so wirklich weit gekommen waren sie
wohl auch nicht.

AVR-Ada

Hmm, der Artikel ist so lange schon nicht mehr angefasst worden, dass
der Wiki-Link nach Sourceforge stale ist. :(  Ich korrigier' ihn mal.

von Nop (Gast)


Lesenswert?

W.S. schrieb:

> Ähem.. ich kann das nur so verstehen, daß du zu den Leuten gehörst, die
> zu allererst int main(... hinschreiben und sich dann sagen "ach mir wird
> schon noch was einfallen". Ist das so?

Nein. Du kannst es auch so verstehen, daß ich z.B. ganz gerne eine 
Sortierfunktion für typkompatible Arrays unterschiedlicher Länge hätte. 
Das geht in Pascal nicht, weil idiotischerweise die Arraylänge Teil des 
Typs ist.

Die vollkommen kranke Stringlogik von Pascal will ich auch nicht mit 
maximal 256, und dann muß man auch alle Strings immer in derselben Länge 
nehmen, selbst wenn man nur 10 Zeichen braucht, weil das idiotische 
Typensystem von Pascal sonst zwischenhaut. Die Strings SIND Arrays.

Ich möchte außerdem auch bei Bedarf Pointercasting haben, damit ich z.B. 
memory-mapped IO-Devices mit voller Breite ansprechen kann, weil der 
Durchsatz damit massiv höher geht. Auf nem ARM7-TDMI habe ich damit den 
Durchsatz zu einem Ethernetchip verdreifacht. Loop-Unrolling war 
natürlich auch mit von der Partie.

Alleine schon eine schnelle Kopierschleife von Speicherbereichen mit 
Alignment-Check braucht Bitpfriemelei mit Pointern und 
Pointerarithmetik, das geht in Pascal allenfalls mit Inline-Assembler.

Ich will nicht diesen Mist mit den Pascal-Schleifen, wo ich weder break 
noch continue habe und entweder umständlich mit Hilfsflags rumfiddeln 
muß oder unnütze Durchläufe habe. Ach ja, und for-loops gibt's auch nur 
mit Inkrement 1.

Ich will auch nicht den Unfug, daß die Auswertung logischer Ausdrücke 
keine definierte Reihenfolge hat und man daher einen Nullpointercheck 
auf einem höheren Blocklevel als die Dereferenzierung machen MUSS.

Prä- und Postinkrement gibt's auch nicht, was den ganzen Sermon noch 
mehr aufbläht. Hoffentlich ist der Compiler überhaupt schlau genug, das 
bei der Umsetzung in Maschinencode trotzdem hinzukriegen.

Ich will auch mal temporär einen Buffer umwidmen können, was in C mit 
Pointercasting sehr elegant geht (wenn man im Kopf behält, daß die alten 
Inhalte des Buffers mit dieser Zugriffsart wegen Aliasing als 
undefiniert betrachtet werden müssen).

Goto brauche ich hin und wieder, weil ich nicht wie in Pascal ein 120 
Ebenen tiefes Nesting hingefrickelt haben will und auch nicht die 
Code-Duplikation bei gestackten Aufräumaktionen der Fehlerbehandlung 
will.

Und noch einiges mehr, ich lasse es dabei aber mal bewenden. Ich brauche 
all das nicht IMMER, aber ich habe es als Werkzeug, weil C eben nicht 
auf Müsli beschränkt ist. Weil C nicht für Anfänger gemacht worden ist, 
die mit diesen Werkzeugen ohnehin nur Schaden anrichten würden.

Ach ja, zu kritisieren an C im Hinblick auf fehlende Sachen wäre da 
natürlich die Abwesenheit des arithmetischen ifs, was es in Fortran mal 
gab, aber selbst dort wurde es dann rausgeworfen. Das hätte man gerne in 
C noch einbauen können. Also das if mit den drei Ausgängen.

> Gehst du denn überhaupt nicht planvoll an deine Arbeit?

Doch, und im Normalfall achte ich auf Typeneinheit. Es sind vielleicht 
10% des Codes, wo ich die fieseren Seiten von C raushole. Aber der Punkt 
ist, mit Pascal gingen diese 10% nicht.

Sind das lowlevel-Aspekte? Ja. Aber genau für 
lowlevel-Systemprogrammierung IST C GEMACHT.

> Ich sag dir mal eins:
> dein "sondern ich will, daß der Compiler das umsetzt, was ich sage,
> Punkt." ist so ziemlich das Falscheste, was man sich wünschen kann.

Nein, das ist exakt die Einstellung, für die C überhaupt erst gemacht 
wurde. Wenn Du nicht so denkst, dann laß es einfach sein, mit C zu 
programmieren, diese Sprache ist nicht für Dich gemacht.

Ich rege mich eher auf, wenn der Compiler tut, wa sich ihm nicht gesagt 
habe. Beispielsweise die total kaputte Inline-Logik des GCC, die im 
Wesentlichen tut, was sie will - es sei denn, ich halte ihn mit 
haufenweise Funktionsattributen im Zaum.

> Es ist eben Mumpitz, den jeder für sich machen
> kann und es ist NICHT eine tatsächliche Sprachänderung. Kapiere das mal.

Man BRAUCHT dafür auch keine Sprachänderung, kapiere das mal. Man muß 
nicht jeden Schnickschnack in die Sprache reinstopfen. Der Punkt ist, ja 
das haben vorher alle gemacht. IRGENDWIE. Das ist jetzt einheitlich.

> Das sind mal wieder zwei verschiedene Dinge. Pascal hat die Fähigkeit,
> an zukünftige Anforderungen angepaßt zu werden.

Pascal hat die Fähigkeit, komplett zu verschwinden, und ist auf einem 
guten Weg dahin. Eigentlich IST Pascal längst tot, weil die Sprache 
dermaßen untauglich war, daß sie an allen Ecken mit zu nichts 
kompatiblen Dialekt-Erweiterungen aufgebohrt wurde. Mit Pchar hat man in 
manchen Dialekten übrigens endlich auch mal vernünftige Strings. 
C-Strings.

> Sag's anders herum: Dort, wo man moderne Dinge wie GUI's benötigt - also
> überall auf allen PC's dieser Welt einschließlich aller Smartphones,
> Tablets, Navis - kann man C nicht wirklich einsetzen

Korrekt. Ich habe GUI-Programmierung unter Xwindow in reinem C gemacht, 
das ist zum Abgewöhnen. Dafür nimmt man sinnigerweise Frameworks, wenn 
man in endlicher Zeit fertigwerden will.

> Also bleibt noch die Welt der Kommandozeile

Und Mikrocontroller. Was für ein Zufall, daß diese Webseite hier 
ausgerechnet mikrocontroller.net heißt. ;-)

> gröhl... mal im Ernst: was soll das bitte?

Wenn Du keine Fehlerbehandlung machen willst, bitte. Dann brauchst Du 
sie vielleicht. Ich komme noch aus einer Zeit, wo sämtliche Inputs vor 
der Verarbeitung zu validieren waren.

> Jetzt übertreibst du es aber gar zu sehr. C kennt keine Strings. Punkt.

Pascal auch nicht. Strings sind in nem Header definiert als array of 
char - und alle mit derselben Länge wegen des dämlichen Typensystems.

> Wie oft dort wieder und wieder jede blöde Zeichenkette nach
> diesem abgesucht wird (strlen), anstatt sich die aktuelle Länge mal auf
> intelligentere Weise zu merken, ist grauenvoll.

Ach was. Und in Pascalstrings kannste einen Texteditor dann viel 
effizienter bauen - außer natürlich, Dein Text sollte mehr als 256 
Zeichen haben. Fasse Dich kurz!

Außerdem ist das kein Defizit von C, sondern der Programmierer. In so 
einer Anwendung macht man das auch nicht mit immer neuem strlen.

> Ja. Sehe ich auch so. Aber man muß es ergänzen mit "Und wo ist eine
> High-Level-Sprache, die man eben für höhere Level benutzen kann? Und die
> so nebenbei den Bereich von C auch mit abdeckt?"

C++ ist es jedenfalls nicht. Also wenn man so eine Konstellation hat, 
würde ich eher für die Speedkracher auf C setzen und das dann etwa aus 
Python heraus interfacen. Mit Python hat man dann auch den wesentlichen 
Produktivitätsfaktor, der keineswegs OOP ist (das ist ein Mythos), 
sondern vielmehr automatisches Speichermanagement.

von mec (Gast)


Lesenswert?

W.S. schrieb:
> Low Level war früher, da wurde jedes Kilobyte an RAM mit Gold
> aufgewogen.
>
> Heutzutage braucht man was Anderes, nämlich Programmiersprachen, die:
>
> - moderne Programmelemente (GUI) und Beherrschung größerer Datenelemente
> (Objekte und Kapselung) besser machen als C

Einen XLP PIC12F möchte ich aber doch lieber in C Programmieren geht 
schneller als in Assembler, und die Baterie sollte doch einige Jahre 
halten. Für das was du willst gibt es ja schon lange C++ ;)

von Teo (Gast)


Lesenswert?

mec schrieb:
> Einen XLP PIC12F möchte ich aber doch lieber in C Programmieren geht
> schneller als in Assembler, und die Baterie sollte doch einige Jahre
> halten. Für das was du willst gibt es ja schon lange C++ ;)

Bügelt auch weniger Falten aus dem Hirn :)
Aber nur OHNE XC Compiler in der Free Version!

von Rolf M. (rmagnus)


Lesenswert?

W.S. schrieb:
>> Falsch, C99 beispielsweise hat auch portable Datentypen eingeführt.
>
> O jemine, schon wieder dieser unselige Krempel. Da hat überhaupt keiner
> irgendwas eingeführt, sondern es war die finale Kapitulation. Und zwar
> in der Form, daß man gesagt hat "Leute macht euch für eure partikuläre
> Architektur eine Headerdatei, wo ihr reinschreibt typedef unsigned long
> uint32_t; und so weiter.

Falsch!

> Sowas haben Legionen von Leuten zuvor schon längst gemacht mit u32 oder
> anderen selbstausgedachten Namen. Jedem C-Compiler ist das völlig
> schnurz. Er kennt all dieses Zeugs nur dann, wenn man ihm so eine
> Headerdatei zuvor in den Rachen geworfen hat.

Falsch!

> Sowas kann jeder, du könntest dir auf diese Weise auch nop32_t oder
> T32NOP oder sonstwas kreieren. Es ist eben Mumpitz, den jeder für sich
> machen kann und es ist NICHT eine tatsächliche Sprachänderung. Kapiere
> das mal.

Kapiere du doch bitte mal, dass das zwar nicht im Sprachkern enthalten 
ist, aber sehr wohl in der ISO-Norm, die die Sprache beschriebt. Jeder 
C99-konforme Compiler muss diesen Header mitbringen, mit genau den 
Typnamen, wie sie in der ISO-Norm vorgegeben sind. Die Idee ist gerade 
die, dass nicht mehr jeder die Typen selber mit eigenen Namen definieren 
muss, sondern diese einheitlich sind. Warum die Typen nicht als 
Schlüsselwörter im Sprachkern eingebaut worden sind, hab ich oben schon 
mal erklärt. Du hattest im Gegenzung natürlich wie immer mal wieder 
keine Begründung, warum es anders gelöst sein sollte, wiederholst aber 
regelmäßig lautstark, für wie furchtbar du es hältst.
Offenbar gehört für dich die gesamte Standardbibliothek, die sehr wohl 
als Teil der Sprache zu sehen ist, nicht zu dieser. Was in der 
Standardbibliothek enthalten sein muss, ist genaus festgelegt, wie der 
Rest.

> Ich sagte es ja schon: die Gründe für C sehe ich vorrangig im
> außertechnischen Bereich.

Was auch immer das bedeuten soll. Ich wüßte jetzt nicht, welches 
"außertechnische" System man in C programmieren könnte.

>> In dem Bereich, wo C sinnvoll eingesetzt wird, brauche ich den OOP-Krams
>> nicht. OOP ist sinnvoll für Simulationen (zu denen auch entsprechende
>> Spiele zählen) und GUIs. Sonst ist OOP schlichtweg fehl am Platze.
>
> Sag's anders herum: Dort, wo man moderne Dinge wie GUI's benötigt - also
> überall auf allen PC's dieser Welt einschließlich aller Smartphones,
> Tablets, Navis - kann man C nicht wirklich einsetzen, denn dafür ist es
> zu poplig.

Und doch werkelt in all diesen Geräten eine ganze Menge C-Code. In der 
Regel nicht auf der GUI, aber im Kernel, Treibern und vielen 
Bibliotheken. Denn auch wenn du es nicht glauben magst: Obwohl man von 
der Software nur die GUI sieht, ist die bei weitem nicht das einzige, 
woraus sie besteht.

>> Strings gehen in C als C-Strings tadellos. Man kann sogar Pascalstrings
>> nachbilden, falls man das wollen sollte. Natürlich gibt die Sprache das
>> her.
>
> Jetzt übertreibst du es aber gar zu sehr. C kennt keine Strings. Punkt.

C hat keinen eigenen Datentyp für Strings. Das heißt nicht, dass es sie 
nicht kennt. Stringhandling ist aber wirklich nicht der glorreichste 
Teil von C.

von Dirk B. (dirkb2)


Lesenswert?

W.S. schrieb:
> Wie oft dort wieder und wieder jede blöde Zeichenkette nach
> diesem abgesucht wird (strlen),

Ja, das wird von Anfänger oft falsch gemacht.

Wann braucht man denn vor der Verarbeitung des Strings die Länge?
Beim besorgen von Speicher für eine Kopie und beim Anhängen (strcat).

In den anderen Fällen kannst du bei der Bearbeitung auf den 
Stringterminator achten.

von Dirk B. (dirkb2)


Lesenswert?

Das größte Problem von C ist, dass auch in der Standard Library zuwenig 
auf Buffer Overflows geachtet wird.

Man hätte schon 1989 alle betroffenen Stringfunktionen so erweitern 
müssen, dass die Größe des Zielbereichs mit angegeben wird.

von Le X. (lex_91)


Lesenswert?

Jörg W. schrieb:
> Ja, vermutlich schon.  Es gab ja auch mal Ansätze für eine Portierung
> von GNU Ada auf den AVR, aber so wirklich weit gekommen waren sie
> wohl auch nicht.

Wie muss man sich so eine Portierung eigentlich vorstellen?
Ich meine mich zu erinnern dass der gcc ja mehrere Zwischenkompilate 
erzeugt, Bytecode (GIMPL?) usw.

Ein Ada-Frontend existiert ja (GNAT).
Ein AVR-Backend auch (als Teil des avr-gcc).

Ich dachte bisher, das Frontend würde einfach plattformunabhängigen 
Bytecode produzieren. Der Teil des gcc, der dann letzlich Assemblercode 
für AVR produziert hat ja eigentlich keine Berührungspunkte mehr zur 
ursprünglichen Sprache, dem stört es doch nicht ob das mal C oder Ada 
war.

Oder ist das alles nicht so sauber getrennt wie ich mir das vorstelle?

: Bearbeitet durch User
von mec (Gast)


Lesenswert?

Dirk B. schrieb:
> Das größte Problem von C ist, dass auch in der Standard Library zuwenig
> auf Buffer Overflows geachtet wird.
>
> Man hätte schon 1989 alle betroffenen Stringfunktionen so erweitern
> müssen, dass die Größe des Zielbereichs mit angegeben wird.

Dafür gibt es ja C++ ;)

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Dirk B. schrieb:
> Man hätte schon 1989 alle betroffenen Stringfunktionen so erweitern
> müssen, dass die Größe des Zielbereichs mit angegeben wird.

strcpy, strcat, sprintf etc. haben allesamt Äquivalente mit 
Größenangabe; die "ollen Kamellen" musste man schon 1989 nicht mehr.

Rausschmeißen aber ging nicht, weil anders als bei akademischen 
Lehrsprachen die Wart- und Weiterverwendbarkeit von existierendem Code 
bei C nicht unwichtig ist. Akademische Lehrsprachen können sich leisten, 
allen bisher geschriebenen Code wegzuwerfen (ist ja eh' nur dazu da, zu 
Lehrzwecken geschrieben zu werden), Sprachen, die in einem produktiven 
Kontext eingesetzt werden, können das nicht.

Unbestritten: C vor C89 war eklig, widerwärtig und bäh. Aber es gibt 
(resp. gab) auch vor 1989 schon in C geschriebene erhaltenswerte 
Software, die aufgrund ihres Codeumfanges in "reines" C89 umzuschreiben 
ein Wahnwitz gewesen wäre, zumal in der Übergangszeit durchaus auch noch 
Mischbetrieb möglich sein musste (der gleiche Code musste auf System A 
und System B verwendbar sein, für System A gab es einen C89-Compiler, 
aber für System B nicht).

Und im Produktiveinsatz ist oft einfach nicht die Zeit vorhanden, um 
erpropt funktionierenden Code nur wegen eines neuen Sprachstandards zu 
überarbeiten.

Freunde akademischer Lehrsprachen ist so eine Problemstellung natürlich 
völlig schnuppe.

von (prx) A. K. (prx)


Lesenswert?

Rufus Τ. F. schrieb:
> Software, die aufgrund ihres Codeumfanges in "reines" C89 umzuschreiben
> ein Wahnwitz gewesen wäre,

Wie etwa Unix und die üblichen Systemprogramme, Compiler, ...

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


Lesenswert?

Le X. schrieb:
> Ich meine mich zu erinnern dass der gcc ja mehrere Zwischenkompilate
> erzeugt, Bytecode (GIMPL?) usw.

Er produziert direkt Assembler. Intern gibt es Zwischencodestadien, aber 
das spielt nach aussen hin keine Rolle.

> Ich dachte bisher, das Frontend würde einfach plattformunabhängigen
> Bytecode produzieren.

Intern wird über abstrakte Zwischenstufen wie Baumdarstellungen 
(GENERIC, GIMPLE) ein schon eher an Maschinen erinnernder Zwischencode 
RTL (Register Transfer Language) erzeugt. In diesen Teilen finden die 
meisten Optimierungen statt. Danach wird die RTL in den Assembler-Code 
der Zielmaschine umgesetzt.

Dieser Zwischencode ist aber normalerweise eine rein programminterne 
Darstellung, d.h. er taucht nicht einer externalisierten Form auf, wie 
es etwa Bytecode wäre.

> Der Teil des gcc, der dann letzlich Assemblercode
> für AVR produziert hat ja eigentlich keine Berührungspunkte mehr zur
> ursprünglichen Sprache, dem stört es doch nicht ob das mal C oder Ada
> war.

Im Prinzip ja. Allerdings müssen sich für neue Frontends alle Elemente 
der Quellsprache brauchbar auf den Zwischencode abbilden lassen. So gäbe 
es beispielsweise ohne eine Zwischencodedarstellung des Operators ?: 
sicherlich Problem mit der Umsetzung von C/C++.

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


Lesenswert?

A. K. schrieb:
> Wie etwa Unix und die üblichen Systemprogramme, Compiler, ...

Naja, in den vergangenen 25 Jahren wird da schon etliches überarbeitet 
worden sein, so daß man in den aktiven Teilen davon jetzt kaum noch 
auf alten K&R-Code treffen dürfte.

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

W.S. schrieb:
> Anmerkung zur Effizienz: Es ist geradezu grauselig, was für einen
> unnötigen Ressourcenverbrauch das unselige Nullbyte verursacht. Man
> schaue mal in ein x-beliebiges C-Programm hinein, das mit irgendwelchem
> Text umgeht. Wie oft dort wieder und wieder jede blöde Zeichenkette nach
> diesem abgesucht wird (strlen), anstatt sich die aktuelle Länge mal auf
> intelligentere Weise zu merken, ist grauenvoll.

Was hindert Dich daran, eigene effizientere String-Funktionen zu 
schreiben?

von (prx) A. K. (prx)


Lesenswert?

Rufus Τ. F. schrieb:
> Naja, in den vergangenen 25 Jahren wird da schon etliches überarbeitet
> worden sein, so daß man in den aktiven Teilen davon jetzt kaum noch
> auf alten K&R-Code treffen dürfte.

Klar. Aber bei mir auf der Platte finde ich noch K&R Code. ;-)

: Bearbeitet durch User
von Operator S. (smkr)


Lesenswert?

Rufus Τ. F. schrieb:
> Rausschmeißen aber ging nicht, weil anders als bei akademischen
> Lehrsprachen die Wart- und Weiterverwendbarkeit von existierendem Code
> bei C nicht unwichtig ist.

Dieser Meinung bin ich nicht, auch wenn stark vertreten in der 
Programmiergemeinde. Bei jeder Version (C89, C99, C11...) hätte man die 
"gefährlichen" Funktionen rausschmeissen müssen und bessere integrieren. 
Dies hätte dazu geführt, dass ein saubererer Programmierstil entwickelt 
worden wäre, statt sich an den alten Funktionen festzuhalten, ganz im 
Sinne von: Sie funktionieren ja noch. Nur um diesen paar Funktionen 
wegen, muss man aber auch nicht gleich eine gesamte neue Sprache 
erschaffen. Wenn man als Analogie unsere gesprochenen Sprachen nimmt, so 
werden auch schreibweisen obsolet und später schlicht falsch, wenn man 
sie weiterhin wie vor zig Jahren schreibt. 99% der Sprache bleiben aber 
erhalten.

Was die Wiederverwendbarkeit angeht: Das wäre sogar heute möglich, ohne 
dass die Sprache einen Bruch erlitten hätte - compilerswitches.
Wenn ein Programm in C89 geschrieben wurde, muss man es nicht nach C99 
portieren. Man kann, aber das ist dann mit etwas Arbeit verbunden. Und 
wenn man nicht möchte, dann programmiert man auch in 2016 noch in C89.

C++14 hat diesen Schritt nicht gescheut und std::gets gestrichen. Wer 
diese Funktion weiterhin benutzen möchte, programmiert nach wie vor in 
C++03 oder C++11 und wird nicht zum "upgrade" gezwungen.

von (prx) A. K. (prx)


Lesenswert?

Operator S. schrieb:
> Dieser Meinung bin ich nicht, auch wenn stark vertreten in der
> Programmiergemeinde. Bei jeder Version (C89, C99, C11...) hätte man die
> "gefährlichen" Funktionen rausschmeissen müssen und bessere integrieren.

Dann wäre der Standard ignoriert worden und die Compilerbauer hätten den 
alten Kram auf eigene Rechnung drin gelassen, mindestens als Option. Die 
normative Kraft des Faktischen schlägt Ideologie.

von temp (Gast)


Lesenswert?

W.S. schrieb:
> Anmerkung zur Effizienz: Es ist geradezu grauselig, was für einen
> unnötigen Ressourcenverbrauch das unselige Nullbyte verursacht. Man
> schaue mal in ein x-beliebiges C-Programm hinein, das mit irgendwelchem
> Text umgeht. Wie oft dort wieder und wieder jede blöde Zeichenkette nach
> diesem abgesucht wird (strlen), anstatt sich die aktuelle Länge mal auf
> intelligentere Weise zu merken, ist grauenvoll.

Au weia. Soll es jetzt besser sein zu jedem 3 Byte langen String 4 bzw. 
8Byte Länge vorzuhalten? Untersucht mal eure Programme! 90% der Strings 
sind für Fehlermeldungen und noch dazu konstant (beim µC im Flash). Eine 
0 am Ende ist die kürzeste Form den String darzustellen. Und ja mich 
nervt das auch mächtig wenn ich die Fehlermeldungen wegen dem 
schnarchlangsamen strlen() 10nS später zu sehen bekomme...
Jedes richtige Programm das mit Text umgeht muss sich den ja irgendwo 
dynamisch Speichern. Wie und wo das passiert möchte aber immer noch ich 
entscheiden und nicht so ein bekloppter Pascal-Erfinder. Nur gut dass es 
schon zur Zeit als C erfunden wurde Leute gab die wussten um was es 
geht. Die 0 am Ende eines Strings als unsegliche Resourcenverschwendung 
zu bezeichnen ist einfach nur lächerlich.
Ich wage mal eine Aussage und lasse mich auch gern von was anderem 
Überzeugen: Fast alles ausser C(C++) was man heute so als Hochsprache 
bezeichnet ist in C(C++) entwickelt worden. Und deren 
String-Implementierungen haben zusätzlich zur mitgeschleppten Länge auch 
noch eine 0 (oder 2 bei Unicode) am Ende. Jedenfalls ist das bei JAVA, 
JavaScript und Php so. Hätten die Entwickler doch lieber mal W.S. 
gefragt...

von Nop (Gast)


Lesenswert?

Operator S. schrieb:
> Dies hätte dazu geführt, dass ein saubererer Programmierstil entwickelt
> worden wäre, statt sich an den alten Funktionen festzuhalten, ganz im
> Sinne von

C ist keine Lehrsprache, wie schon geschrieben wurde. Die Philosophie 
von C ist, daß der Programmierer verantwortlich ist. C ist nicht fürs 
Pascal-hafte Händchenhalten. Deswegen war es klar, daß man die 
Programmierer nicht zu ihrem vermeintlichen Besten zwingen würde.

Zweitens wäre es bei den Stringfunktionen strcpy/strcat sinnlos, sie zu 
streichen, um die Leute zu zwingen. Es sind Dreizeiler, die man mit 
Leichtigkeit selber schreiben kann.

Drittens setze ich gelegentlich diese älteren Funktionen auch heute noch 
ein. Nämlich dann, wenn ich die Inputs bereits vorher validiert habe und 
auf Geschwindigkeit optimieren will. Oder wenn es um Strings geht, die 
das Programm nicht von außen empfangen hat, sondern selber generiert 
hat.

Strcpy ist nämlich nicht per se gefährlich, sondern nur dann, wenn man 
die Länge des src-Strings nicht kennt und daher nicht weiß, ob das in 
den dst-Buffer paßt.

von Nop (Gast)


Lesenswert?

temp schrieb:
> Eine
> 0 am Ende ist die kürzeste Form den String darzustellen.

WS wollte hier wohl kaum auf den Speicherverbrauch hinaus, der bei 
Pascalstrings ja genauso hoch ist - Byte 0 ist beim Pascalstring ja 
dessen Länge.

Worum es ging, ist Ressourcenverbrauch im Sinne von verschwendeter 
CPU-Zeit. Und ja, wenn man sich mit C-Strings blöd anstellt, dann kann 
man damit  O(n^2)-Sachen fabrizieren, die sich aber im Quelltext als 
O(n) tarnen, das stimmt. Wenn man sich nicht blöd anstellt, existiert 
dieses Problem aber nicht.

Andererseits kann man auch in Pascal große Datenmengen mit einem 
Bubblesort sortieren, ohne daß man das jetzt der Sprache vorwerfen 
würde.

Und außerdem wird man bei längeren Texten, wo man überhaupt solche 
strlen-Probleme hat, auch in Pascal letztlich auf ein größeres 
char-Array zurückgreifen, weil Pascalstrings für die Länge nur ein Byte 
haben, also 255 Zeichen zulassen.

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


Lesenswert?

Le X. schrieb:
> Oder ist das alles nicht so sauber getrennt wie ich mir das vorstelle?

In der Praxis hast du auf jeden Fall irgendwelche Wechselwirkungen.

Soweit ich verstanden habe, kommt bei Ada noch hinzu, dass im
Sprachumfang sehr viel mehr an Hintergrund-Bibliothek festgeschrieben
ist (bis hin zu Multitasking) als bei C, sodass eine Implementierung,
bevor sie sich „komplett“ nennen darf, sehr viel mehr Arbeit hat.

Allerdings ist auch AVR-GCC/avr-libc nicht strikt konform mit dem
C-Standard.  Das fängt an mit zu kleinen double-Datentypen (ein Byte
mehr hätte genügt für Konformität, wäre aber ansonsten ein im GCC
völlig unüblicher Datentyp, und 64 bit wollte man wohl damals lieber
nicht dafür abstellen), aber auch einige Teile der Bibliothek fehlen,
die vom Standard vorgeschrieben wären: wchar gibt's gar nicht, aber
auch sonst fehlt hie und da mal was, weil's auf einem Controller nicht
so viel Sinn hat.  Ist letztlich ein offensichtlich einigermaßen
brauchbarer Kompromiss, der für die meisten Nutzer nahe genug am
C-Standard ist, als dass er von ihnen angenommen worden ist.

von Stefan F. (Gast)


Lesenswert?

> Bei jeder Version hätte man die
> "gefährlichen" Funktionen rausschmeissen müssen

Das hat man nicht einmal bei Java gemacht. Ich kenne kein einziges 
deprecated Java Feature, das tatsächlich entfernt wurde.

Wenn das schon bei Java (der "wir machen alles besser" Sprache) nicht 
gemacht wurde, dann bei C erst Recht nicht. Es wird gute Gründe dafür 
geben, die nicht jedem hier ersichtlich sind. Einige wurden ja schon 
genannt.

C ist ganz sicher in vielerlei Hinsicht nicht ideal. Die Sprache wird 
nicht mehr weiter entwickelt. Man muss sie daher so nehmen, wie sie ist, 
oder man nimmt was anderes. Über ihre Unzulänglichkeiten zu diskutieren 
ist völlig unsinnig.

Wir könnten hier genau so gut über die deutsche Sprache diskutieren. Das 
wäre ebenso Sinnlos.

Jeder der hier von der Arbeit mit C abraten tut, sollte auch vom 
deutsch-Sprechen abraten. Und jeder, der meint, er müsse die Sprache 
verteidigen, kann ja mal versuchen, den Franzosen deutsch nahezulegen.

Völlig Sinnlos ist das!

von Jobst Q. (joquis)


Lesenswert?

Rolf M. schrieb:
> Stringhandling ist aber wirklich nicht der glorreichste
> Teil von C.

Was glorreich auch immer heißen mag, aber ich arbeite sehr viel mit 
Strings und ich kenne keine Sprache, die da mehr ermöglicht als C.

Eine Menge zu kritisieren hab ich nur an Library-Funktionen. Zum 
Bleistift dass strcpy(), strcat() und Verwandte den Stringanfang 
zurückgeben, der ja eh schon bekannt ist und als Argument übergeben 
wird, anstatt den viel informativeren Zeiger auf das Stringende. 
Vermutlich ein Kompromiss wegen dem vielen Unverständnis, das Anhänger 
von Lehrsprachen dem Programmieren mit Zeigern entgegenbringen.

Unverständlich ist mir auch die Rückgabe von NULL in Funktionen wie 
strchr(), wenn kein Zeichen gefunden wurde. Auch hier wäre ein Zeiger 
auf das Nullzeichen am Ende praktischer, denn das wäre zwar ein leerer, 
aber gültiger String, während NULL zwingend eine Extrabehandlung 
erfordert.

Aber das sind keine Mängel der Sprache oder String-Konvention, sondern 
der Library. Niemand zwingt mich, sie zu verwenden, ich kann mir eigene 
schreiben, die meinen Ansprüchen genügen.

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


Lesenswert?

Jobst Q. schrieb:
> kenne keine Sprache, die da mehr ermöglicht als C.

Naja, Python oder Perl könnte ich dir da sofort nennen. :)

von (prx) A. K. (prx)


Lesenswert?

Jobst Q. schrieb:
> Was glorreich auch immer heißen mag, aber ich arbeite sehr viel mit
> Strings und ich kenne keine Sprache, die da mehr ermöglicht als C.

Sie ermöglicht auch, sich selbst ins Knie zu schiessen. Das kann man gut 
finden, weil man das als perfekter Programmierer natürlich nicht tut. 
Oder schlecht, weil man das als normaler Programmierer manchmal doch 
tut.

Was passieren kann, wenn man bei der Längenberechnung in einem 
speziellen Fall auch nur um ein einziges Byte daneben liegt, kann man 
sehr schön hier lesen: 
https://daniel.haxx.se/blog/2016/10/14/a-single-byte-write-opened-a-root-execution-exploit/

Aber das passiert den hiesigen Programmierern selbstverständlich nie.

: Bearbeitet durch User
von Rolf Magnus (Gast)


Lesenswert?

Jobst Q. schrieb:
> Rolf M. schrieb:
>> Stringhandling ist aber wirklich nicht der glorreichste
>> Teil von C.
>
> Was glorreich auch immer heißen mag,

Damit meinte ich, dass Stringhandling sehr mühsam und fehlerträchtig ist 
im Vergleich zu anderen Sprachen. Klar hat man dafür mehr in der Hand 
und kann auf µCs sehr viel besser mit dem begrenzten Speicher und dessen 
Aufteilung in RAM und Flash umgehen. Aber auf dem PC tue ich mir nicht 
ausgedehnte Arbeiten mit Strings in C an. Da nehme ich lieber Python 
oder C++ mit Qt oder so.

> aber ich arbeite sehr viel mit Strings und ich kenne keine Sprache, die
> da mehr ermöglicht als C.

C bringt ja noch nicht mal reguläre Ausdrücke mit.

> Eine Menge zu kritisieren hab ich nur an Library-Funktionen.

Was ist denn für dich das Stringhandling von C, wenn nicht die 
Library-Funktionen? Im Sprachkern ist ja wirklich nichts dafür 
enthalten. Gut, man kann noch alles Zeichen für Zeichen von Hand 
behandeln, aber dann baut man auch nur die Library-Funktionen nach.

> Unverständlich ist mir auch die Rückgabe von NULL in Funktionen wie
> strchr(), wenn kein Zeichen gefunden wurde. Auch hier wäre ein Zeiger
> auf das Nullzeichen am Ende praktischer, denn das wäre zwar ein leerer,
> aber gültiger String, während NULL zwingend eine Extrabehandlung
> erfordert.

Die braucht man doch sowieso. Ich suche ein Zeichen, und wenn es nicht 
gefunden wird, muss ich diesen Fall eh separat behandeln. Im übrigen 
kann man mit strchr auch explizit nach dem \0 selbst suchen. Ob man das 
braucht, sei mal dahingestellt, aber es ginge nicht, wenn dessen Adresse 
auch dann zurückgegeben würde, wenn das gesuchte Zeichen gar nicht 
gefunden wird.

von Yalu X. (yalu) (Moderator)


Lesenswert?

Operator S. schrieb:
> Bei jeder Version (C89, C99, C11...) hätte man die "gefährlichen"
> Funktionen rausschmeissen müssen und bessere integrieren.

Die meisten der oft als "gefährlich" genrandmarkten Funktionen sind ja
nicht grundsätzlich gefährlich. In vielen Kontexten können sie
unbedenklich eingesetzt werden, nur eben nicht in allen.

Da es für die gefährlichen Anwendungsfälle teilweise keine sinnvolle
Alternativfunktionen gab, wurde diese nachträglich hinzugefügt. Das
heißt aber nicht, dass die Originalfunktionen deswegen obsolet sind.

Die einzige Ausnahme stellt gets dar. Diese Funktion ist fast immer
gefährlich und wurde deswegen – ganz deinem Wunsch entsprechend – in C11
rausgeschmissen.

von Jobst Q. (joquis)


Lesenswert?

Jörg W. schrieb:
> Jobst Q. schrieb:
>> kenne keine Sprache, die da mehr ermöglicht als C.
>
> Naja, Python oder Perl könnte ich dir da sofort nennen. :)

Das ist eine andere Ebene. Da hat man eine umfangreichere Library, ist 
für viele bequemer, die lieber Referenzbücher studieren, als sich die 
einfachen Grundlagen der Zeigerprogrammierung anzueignen.

Was in C möglich ist, zeigt sich bei Problemen, die nicht zu den 
Standardaufgaben gehören, die von den Library-Entwicklern berücksichtigt 
wurden.

Der Unterschied zwischen Highlevel-Sprachen und C ist wie zwischen 
LEGO-Baukasten und Werkzeugkasten. Sicher kann man mit LEGO schneller 
ein Haus bauen, aber vom Hausbau hat man dadurch wenig begriffen.

von Nop (Gast)


Lesenswert?

A. K. schrieb:
> Was passieren kann, wenn man bei der Längenberechnung in einem
> speziellen Fall auch nur um ein einziges Byte daneben liegt, kann man
> sehr schön hier lesen

Nur hat das mit C-Strings nichts zu tun, weil der Berechnungsfehler mit 
einem escape'ten Punkt am Ende zu tun hatte. Mit anderen Worten, das lag 
am StringINHALT und wäre bei jeder anderen Implementation von Strings 
ebenfalls passiert.

von Konstantin F. (Firma: "Konniemara") (konstantin-2)


Lesenswert?

In c muss man nicht so viel konkretes Wissen über 'howto' haben. Man 
muss einige Sachen verstanden haben und damit kann man sich dann extrem 
viel ausdenken. Also auch ohne auf externe libraries zurückzugreifen.

Oben genanntes Python ist da ja grundverschieden. Da muss man dann genau 
wissen, was vom immensen Umfang geboten wird und wie das geht. Das meint 
Jobst vermutlich mit "Referenzbücher studieren".

Das ist auch gar nicht von der Hand zu weisen. Wertfrei und ohne dass 
ich jetzt das eine oder andere präferieren würde. Von meiner Neigung her 
finde ich dann c angenehmer, eben wegen des größeren Freiheitsgrades.
Python oder allgemein komplexe Sprachen geht man heutzutage aber 
wahrscheinlich so an, dass man sein Problem in Google tippt und das 
Codestück was ausgespuckt wird dann kopiert.
Ist bei meinen .net Exkursionen eigentlich auch so gelaufen. Von sich 
alleine heraus ausdenken kann man sich halt weniger.

Das sind aber auch von der Ausrichtung der Sprachen irgendwie Äpfel und 
Birnen...

von nicht"Gast" (Gast)


Lesenswert?

Yalu X. schrieb:
> Da es für die gefährlichen Anwendungsfälle teilweise keine sinnvolle
> Alternativfunktionen gab, wurde diese nachträglich hinzugefügt. Das
> heißt aber nicht, dass die Originalfunktionen deswegen obsolet sind.

hm, komisch. wenn ich sprintf verwenden will, sagt mein compiler 
(VC)genau das. Er bemeckert, dass die Funktion deprecated ist.

von (prx) A. K. (prx)


Lesenswert?

Nop schrieb:
> Nur hat das mit C-Strings nichts zu tun, weil der Berechnungsfehler mit
> einem escape'ten Punkt am Ende zu tun hatte. Mit anderen Worten, das lag
> am StringINHALT und wäre bei jeder anderen Implementation von Strings
> ebenfalls passiert.

Der Rechenfehler wäre auch passiert. Aber das Programm hätte das Ende 
des allozierten Speichers nicht überschrieben und wäre wahlweise 
abgekackt oder hätte im Ziel das letzte Byte weggelassen und dann nicht 
richtig funktioniert. Es wäre aber kein root exploit draus geworden.

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


Lesenswert?

Konstantin F. schrieb:
> Python oder allgemein komplexe Sprachen geht man heutzutage aber
> wahrscheinlich so an, dass man sein Problem in Google tippt und das
> Codestück was ausgespuckt wird dann kopiert.

Nee, für Python trifft das ganz gewiss nicht so zu.

nicht"Gast" schrieb:
> wenn ich sprintf verwenden will, sagt mein compiler (VC)genau das. Er
> bemeckert, dass die Funktion deprecated ist.

Visual C und aktuelle C-Standards sind doch ohnehin unversöhnliche
Gegensätze.

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


Lesenswert?

nicht"Gast" schrieb:
> hm, komisch. wenn ich sprintf verwenden will, sagt mein compiler
> (VC)genau das. Er bemeckert, dass die Funktion deprecated ist.


Warnung 4996. Damit hat MS aber übertrieben, weil die bei auch bei 
Funktionen ausgespuckt wird, die eine Längenangabe haben (wie z.B. 
strncpy).

von Nop (Gast)


Lesenswert?

A. K. schrieb:
> Der Rechenfehler wäre auch passiert. Aber das Programm hätte das Ende
> des allozierten Speichers nicht überschrieben

Nachgehakt hätte das sprachbedingtes, automatisches Bounds-Checking 
bedeutet. Für jeden Zugriff und überall. Aber: nur weil man davon im 
Sourcetext nichts sieht, heißt das nicht, daß das kostenlos zu haben 
wäre. Deswegen hat C das ja auch nicht, weil: keine Compilermagic hinter 
dem Rücken des Programmierers.

Eine Vorstellung, was das für die Performance bedeutet, kann ja ein 
Testlauf unter Valgrind geben.

von Nop (Gast)


Lesenswert?

.. bzw, man kann natürlich auch in C die Zugriffe kapseln und Grenzen 
checken. Daß das hier nicht gemacht wurde, ist aber keine Einschränkung 
von C gewesen, sondern eine Wahl des Programmierers.

von (prx) A. K. (prx)


Lesenswert?

Nop schrieb:
> Nachgehakt hätte das sprachbedingtes, automatisches Bounds-Checking
> bedeutet. Für jeden Zugriff und überall. Aber: nur weil man davon im
> Sourcetext nichts sieht, heißt das nicht, daß das kostenlos zu haben
> wäre.

Korrekt. Aber angesichts der Häufigkeit, wie der mittlerweile 
Sicherheitsprobleme durch buffer overflows auftreten, fände ich etwas 
mehr CPU für diesen Zweck eine sinnvolle Investition.

von (prx) A. K. (prx)


Lesenswert?

Nop schrieb:
> .. bzw, man kann natürlich auch in C die Zugriffe kapseln und Grenzen
> checken. Daß das hier nicht gemacht wurde, ist aber keine Einschränkung
> von C gewesen, sondern eine Wahl des Programmierers.

Das ist - etwas überspitzt formuliert - der Unterschied zwischen 
Assembler und Hochsprache. Man kann alles auch in Assembler machen, aber 
es wird halt etwas umständlicher. Der Sinn von Hochsprachen liegt darin, 
nicht alles selber machen zu müssen.

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


Lesenswert?

A. K. schrieb:
> Aber angesichts der Häufigkeit, wie der mittlerweile Sicherheitsprobleme
> durch buffer overflows auftreten, fände ich etwas mehr CPU für diesen
> Zweck eine sinnvolle Investition.

Ich fände etwas mehr Investition in die Ausbildung der Programmierer und 
in ihre Gehälter sinnvoller - nicht jeder, der mal HTML "programmiert" 
hat und mit etwas Javascript zurechtkam, ist geeignet, auf Werkzeuge wie 
C losgelassen zu werden.

Ja, es gibt Bücher mit Titeln wie "C in 21 Tagen", aber die sind ähnlich 
ernstzunehmen wie Bücher mit Titen wie "21 kg in 21 Tagen abnehmen" ...

von (prx) A. K. (prx)


Lesenswert?

Rufus Τ. F. schrieb:
> Ich fände etwas mehr Investition in die Ausbildung der Programmierer

Man sollte das Eine tun, ohne das Andere zu lassen.

> und in ihre Gehälter sinnvoller

Mehr Gehalt macht einen Programmierer zunächst nur teurer, nicht besser.

Ok, es ist schon was dran. Aber wenn man gute Leute rausekelt, weil sie 
beispielsweise aufgrund von realistischen Einschätzungen von den 
Träumern ringsum bloss als Hemmschuh gesehen werden, dann hilft auch 
kein Geld.

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


Lesenswert?

A. K. schrieb:
> Mehr Gehalt macht einen Programmierer zunächst nur teurer, nicht besser.

Äh, andersrum. Nur wenn man bereit ist, einen Programmierer angemessen 
zu bezahlen, bekommt man einen Programmierer, der nicht billig ist. Wer 
nur Berufsanfängergehälter zahlt, bekommt auch nur Berufsanfänger bzw. 
Berufsanfängerengagement.

von (prx) A. K. (prx)


Lesenswert?

Gib dem gleichen Programmierer mehr Geld und er wird besser?

: Bearbeitet durch User
von Dussel (Gast)


Lesenswert?

A. K. schrieb:
> Gib dem gleichen Programmierer mehr Geld und er wird besser?
Das sollte ich meinem Chef mal als lohnenswerten Versuch vorschlagen :D

(Das war Spaß. Bei meiner Arbeit programmiere ich nicht.)

von Kaj (Gast)


Lesenswert?

A. K. schrieb:
> Gib dem gleichen Programmierer mehr Geld und er wird besser?
You get what you pay for. If you pay peanuts you get monkeys.

von W.S. (Gast)


Lesenswert?

Dirk B. schrieb:
>> Wie oft dort wieder und wieder jede blöde Zeichenkette nach
>> diesem abgesucht wird (strlen),
>
> Ja, das wird von Anfänger oft falsch gemacht.
>
> Wann braucht man denn vor der Verarbeitung des Strings die Länge?
> Beim besorgen von Speicher für eine Kopie und beim Anhängen (strcat).
>
> In den anderen Fällen kannst du bei der Bearbeitung auf den
> Stringterminator achten.

ICH?? Was, ich?

Junge, mir ist es langsam leid. Guck nur ein einziges Mal in die 
Bibliotheksfunktionen von C - falls dir der zugehörige Quellcode zur 
Verfügung steht. Dort findest du bei jeder Stringfunktion ein oder 
mehrmaliges Aufrufen von strlen.

Bevor du also hier von Anfängern schwafelst, solltest du dich besser 
zuvor mal richtig informieren. Der Punkt ist, daß irgendwelche 
sogenannten Stringfunktionen eben keinen tatsächlichen Stringtyp 
ersetzen können. Sowas muß in die Sprachdefinition eingebaut sein und 
der Compiler muß das selber handhaben - SELBER! verstehst du das? Die 
Basis dafür ist, daß man ein sinnvolleres Stringformat bräuchte, wo das 
allgegenwärtige Abklappern der Zeichen einfach nicht nötig ist. Sowas 
kann kein Compiler-Benutzer sich selber schreiben, sowas muß in den 
Compiler eingebaut werden.

Im übrigen gilt das in entsprechender Form auch für die albernen 
uint32_t Masche. Solange der Compiler SELBST keine anderen Datentypen 
kennt als int mit den Geschmacksrichtungen long, short, unsigned, 
signed, so lange ist das Zusammenschreiben irgendwelcher Headerdateien 
nichts als Brimborium und Scharlatanerie. Hier wird dem unerfahrenen 
Programmierer vorgegaukelt, er hätte was Neues, aber es ist nur ein 
neues Geschenkpapier drum gewickelt.


--------

Nun.. ich habe mittlerweile zum Thema eine Theorie:

C ist bekanntermaßen in weiten Teilen nicht logisch aufgebaut, es fehlen 
Basismittel wie z.B. ein Boolean-Datentyp und vieles mehr, also wird das 
per ordre de mufti erledigt.
Das muß ein Schüler der C-Programmiersprache eben auswendig lernen. Er 
muß dazu sich eben dran gewöhnen, daß es an vielen Stellen in C "eben so 
ist wie es ist, basta!".
Nun gewöhnt er sich halt daran, daß Dinge, die ihm zuvor unlogisch oder 
nicht erklärlich sind, eben so sind wie sie sind und er gewöhnt sich 
langsam aber sicher daran, seinen logischen Verstand in solchen Fällen 
nicht mehr zu gebrauchen, sondern kurzerhand das Angeordnete als gegeben 
und einen unumstößlichen Fakt zu verinnerlichen.
Am Ende solch einer mentalen Umwandlung hat so ein Programmerer seinen 
logischen Verstand weitgehend an der Garderobe abgegeben.

W.S.

von (prx) A. K. (prx)


Lesenswert?

Was die Logik angeht, da gab es tatsächlich einen Abstieg, der schon mit 
K&R C begann und mit C89 nicht besser wurde. Die Logik wohlgemerkt. Die 
Sprache wurde besser.

Nur sind Logik und Brauchbarkeit nicht deckend. So ist die Syntax der 
Typdeklaration zwar ziemlich logisch, aber auch ziemlicher Mist. Manche 
lernen sie einfach auswendig, obwohl logisch, weil sie die Logik 
dahinter nicht verstehen.

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


Lesenswert?

Ich muß mich in meiner Theorie ein bissel korrigieren: Es ist bei der 
Gewöhnung an C nicht nur die Logik betroffen.

Frank M. schrieb:
> Was hindert Dich daran, eigene effizientere String-Funktionen zu
> schreiben?

Ich habe das nicht nötig. Ich benutze in solchen Fällen einfach eine 
bessere Programmiersprache als C. Eine, wo sowas eingebaut ist.

Nop schrieb:
> Die vollkommen kranke Stringlogik von Pascal will ich auch nicht

Nun ja, deine Erfahrungen mit Pascal sehen ausgesprochen steinalt aus - 
das ist etwa so, als wenn du heutzutage über K&R-syntax räsonniertest.


Jörg W. schrieb:
>> Da reicht auch eine schmale Implementierung die auf das sbrk ganz
>> verzichten kann.
>
> Ist ja nun aber nicht so, dass es die nicht gäbe.
>
> Ja, man könnte sich allemal technisch elegantere Lösungen wünschen,
> bei denen der Linker bereits entscheiden kann, was im Hintergrund
> tatsächlich an Konvertierungen benötigt wird.

Tja Jörg, die Generalidee bei C war und ist es eben, möglichst garnichts 
an Funktionen in den Compiler einzubauen. Das war dunnemals wegen 
begrenzer Ressourcen auch sehr verständlich, führt aber zu sowas wie 
printf und Formatstrings und dem damit notwendigerweise verbundenen 
Textinterpreter für den Formatstring.

Auf dem PC ist das zumeist wurscht, da hat man heutzutage genug 
Ressourcen, um die immanente Uneffizienz dieser Strategie ignorieren zu 
können. Auf einem kleinen µC sieht das anders aus. Da ist die Strategie 
von Pascal mit str und write als Pseudo-Prozeduren bedeutend besser:

Erstens: nimmt der Compiler die völlig variable Latte an all den 
Parametern selbst auseinander und zerlegt sie in all das, was gebraucht 
wird,

Zweitens: läßt er logischerweise all die Funktionen weg, die konkret 
nicht gebraucht werden

Drittens kann er auch mit variablen Formatangaben zurechtkommen (also 
sowas wie write(A:9:3, B:y*3:y);

Viertens braucht das Verfahren keinen Formatstring und keinen 
zugehörigen Interpreter, weil der Compiler das alles zur 
Übersetzungszeit erledigt und somit zur Laufzeit keine 
Übersetzungsarbeit mehr zu leisten ist.

Der Nachteil wäre dann nur, daß man keine zur Laufzeit generierten 
Formatstrings haben kann.

Im Prinzip wäre sowas auch in C spielend möglich - vorausgesetzt, man 
arbeitet es direkt in die Sprache und in den Compiler ein. Eine 
Realisierung per Bibliotheksfunktion kann es jedoch nicht geben, da der 
Unterschied eben zentral darin besteht, Übersetzungsarbeit entweder 
zur Übersetzungszeit oder zur Laufzeit zu leisten.

Die Chance zu sowas sehe ich alledings zu null an. In C hat man es ja 
nicht mal geschafft, mit Integertypen aufzuräumen UND Zeichentypen 
(char) von numerischen Typen zu trennen.

W.S.

von Yalu X. (yalu) (Moderator)


Lesenswert?

W.S. schrieb:
> Guck nur ein einziges Mal in die Bibliotheksfunktionen von C - falls
> dir der zugehörige Quellcode zur Verfügung steht. Dort findest du bei
> jeder Stringfunktion ein oder mehrmaliges Aufrufen von strlen.

Wirklich bei JEDER? Hast du denn selber nachgeschaut?

Ich habe gerade mal die AVR-Libc durchgegrept. Ergebnis:

In der kompletten Bibliothek gibt es keine einzige Funktion, die strlen
aufruft. strlen wird ausschließlich von User-Code aufgerufen, und dort
auch nur recht selten.

von Carl D. (jcw2)


Lesenswert?

Also ein neues Keyword write, das wie eine Funktion benutzt wird, aber 
eine ganz andere Parameterübergabe hat. Das wäre doch mal innovativ.
(gefundene Ironie darf nach Belieben weiterverwendet werden)

Es mag ja sein, daß sich nicht jedes C-Detail jedem erschließt, aber 
deshalb muß man doch eine Sprache nicht mit neuem, inkonsistenten Zeug 
überladen, nur um Ausgaben auf stdout (hat Pascal sowas) zu machen.

von W.S. (Gast)


Lesenswert?

A. K. schrieb:
> Nur sind Logik und Brauchbarkeit nicht deckend.

Das ist allen verständnisvollen Programmierern völlig klar. Es geht ja 
auch nicht darum hier irgendwas zu verteufeln, sondern es geht darum, 
die Sache einfach nur nüchtern beim Namen zu nennen und dabei auch mal 
deren Grenzen aufzuzeigen.

Der TO hat sich an for(;;) gestoßen - und zu Recht.
Formal ist das nicht falsch, aber es ist unleserlich, denn wir sind 
Menschen und keine Maschinen. Genau deshalb ist sowas eben schlechter 
Stil, denn man könnte das Ziel auf einsichtigere Weise behandeln, ohne 
dadurch irgend etwas an Effizienz zu verlieren.

Weiter oben hat jeman das Wort 'Müslifaktor' gebraucht ("aber wie ich 
schon meinte, den Müslifaktor bei Pascal finde ich unerträglich").
Ich halte das für eine kreuzgefährliche Grundeinstellung. Bieder und in 
einfach gehaltener Quelle zu schreiben und das Optimieren dem Compiler 
zu überlassen, ist also manchem unerträglich. Alles Hasardeure?

Das ist übrigens ein grundlegendes Thema: Viele C-Programmierer glauben 
immer noch, sie könnten durch vigilantische Kunststücke beim Formulieren 
dessen, was sie bezweicken wollen, an Platz sparen und Effizienz 
gewinnen - oder sich wenigstens vor ihren Stallgefährten brüsten.

Das ist heutzutagen nur noch dummer Käse, denn die Compiler sind 
weitgehend sehr viel besser geworden als in der blutigen Anfangszeit. 
Die früher eventuell gewesene Notwendigkeit, selbst etwas zum Optimieren 
beizutragen, ist heutzutage nur noch ein Beitrag zur Unleserlichkeit.

Soviel zu Logik, Brauchbarkeit und dem, was die Leute draus machen.

W.S.

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


Lesenswert?

Yalu X. schrieb:
> In der kompletten Bibliothek gibt es keine einzige Funktion, die strlen
> aufruft.

Ähemm... dann verrate mir doch mal, wie strcat und Konsorten einen 
String an einen anderen dranhängen - per magischem Endpunktfinden?  ;-)

W.S.

von (prx) A. K. (prx)


Lesenswert?

W.S. schrieb:
> Die Chance zu sowas sehe ich alledings zu null an. In C hat man es ja
> nicht mal geschafft, mit Integertypen aufzuräumen UND Zeichentypen
> (char) von numerischen Typen zu trennen.

Eine derart verbreitete Sprache reformiert man unter Wahrung 
weitgehender Kompatibilität, oder man baut unter anderem Namen eine neue 
Sprache wie man sie gerne hätte. Der Versuch, per ideologischem Zwang 
alte häufig gebrauchte Zöpfe abzuschneiden, würde nicht akzeptiert, 
sondern würde nur den offiziellen Sprachstandard von der Realität 
abkoppeln.

Eine Unterscheidung in zueinander nicht zuweisungskompatible Integer, 
Booleans und Chars ist in C nicht reinreformierbar. Die fehlende 
Unterscheidung ist eine Art Axiom von C, ob man es mag oder nicht. Es 
ändern zu wollen brächte eine neue inkompatible Sprache, die irgendwie 
an C erinnert und zwecks Verwirrung auch dummerweise so heisst.

C dafür zu kritisieren, dass es C bleibt, ist also unredlich. Du musst C 
deshalb nicht mögen, aber die Axiome von C sind fixiert.

NB: Von C abgeleitete Sprachen existieren. Eine davon heisst D.

: Bearbeitet durch User
von Dirk B. (dirkb2)


Lesenswert?

Rufus Τ. F. schrieb:
> nicht"Gast" schrieb:
>> hm, komisch. wenn ich sprintf verwenden will, sagt mein compiler
>> (VC)genau das. Er bemeckert, dass die Funktion deprecated ist.
>
>
> Warnung 4996. Damit hat MS aber übertrieben, weil die bei auch bei
> Funktionen ausgespuckt wird, die eine Längenangabe haben (wie z.B.
> strncpy).

strncpy ist auch eine üble Funktion. Wenn die Grenze erreicht ist, wird 
die '\0' nicht mit abgespeichert.

von Jobst Q. (joquis)


Lesenswert?

Rolf Magnus schrieb:
>> Eine Menge zu kritisieren hab ich nur an Library-Funktionen.
>
> Was ist denn für dich das Stringhandling von C, wenn nicht die
> Library-Funktionen? Im Sprachkern ist ja wirklich nichts dafür
> enthalten. Gut, man kann noch alles Zeichen für Zeichen von Hand
> behandeln, aber dann baut man auch nur die Library-Funktionen nach.

Stringhandling ist die Bearbeitung von Strings beim Lesen und Schreiben. 
Da der String in C nichts anderes ist als ein Zeiger auf den Anfang, 
kann man damit alles machen. Im Gegensatz zu Sprachen in denen 
festgelegt ist, was man damit machen kann und was nicht.

C hat eine klare Trennung von Sprache und Librarys und das finde ich 
positiv. Man kann im Prinzip alle Funktionen selbst schreiben und hat 
damit den vollen Überblick, was im Programm geschieht.

>
>> Unverständlich ist mir auch die Rückgabe von NULL in Funktionen wie
>> strchr(), wenn kein Zeichen gefunden wurde. Auch hier wäre ein Zeiger
>> auf das Nullzeichen am Ende praktischer, denn das wäre zwar ein leerer,
>> aber gültiger String, während NULL zwingend eine Extrabehandlung
>> erfordert.
>
> Die braucht man doch sowieso. Ich suche ein Zeichen, und wenn es nicht
> gefunden wird, muss ich diesen Fall eh separat behandeln.

Nicht immer. ZB wenn man über den Punkt die Erweiterung eines 
Dateinamens sucht. Wenn kein Punkt dabei ist, hat er keine Erweiterung 
und der Leerstring ist korrekt.

Wenn es eine Fehlerbehandlung braucht, kann man das mit *s genauso gut 
wie mit s==NULL erkennen.

> Im übrigen
> kann man mit strchr auch explizit nach dem \0 selbst suchen. Ob man das
> braucht, sei mal dahingestellt, aber es ginge nicht, wenn dessen Adresse
> auch dann zurückgegeben würde, wenn das gesuchte Zeichen gar nicht
> gefunden wird.

In C hat jeder String eine \0 und die wird auch von meiner Funktion 
gefunden.

von Stefan F. (Gast)


Lesenswert?

> dann verrate mir doch mal, wie strcat und Konsorten einen
> String an einen anderen dranhängen

Ihr wollt jetzt nicht im ernst um solche Pillepalle Funktionen 
feilschen, oder?

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


Lesenswert?

W.S. schrieb:
> Eine Realisierung per Bibliotheksfunktion kann es jedoch nicht geben, da
> der Unterschied eben zentral darin besteht, Übersetzungsarbeit entweder_
> zur Übersetzungszeit _oder zur Laufzeit zu leisten.

Yep, und damit bist du komplett festgenagelt auf die Ausgabekanäle,
wie sie in den Sprachumfang gegossen worden sind.  Das ist doch genau
einer der Kritikpunkte an Pascal oben, dass man das, was der Compiler
bei write[ln] macht, nicht im eigenen Code ebenfalls zur Verfügung
hat.  Alles, was als Ausgabekanal nicht bereits so ist, dass es von
der Implementierung als "Datei" betrachtet würde, kann man damit
vergessen.

Ich habe die Argumentlisten von writeln nicht mehr gut genug im Kopf,
aber ich glaube mich zu erinnern, dass es an die Variantenvielfalt
von printf-Formatierung nichtmal ansatzweise herankam.

Ehrlich: vor 15 Jahren habe ich noch irgendwo mal ein Controllerprojekt
gehabt, bei dem der Controller so klein war, dass printf() nicht
gepasst hat.  Das war aber auch das letzte Mal, dass mir das passiert
war, vermutlich ein AT90S8535 oder sowas, der aber ansonsten schon
gut mit Gleitkomma vollgestopft war.

Seither habe ich nie ein Problem gehabt, dass einem Controller die
Ressourcen ausgerechnet wegen der Benutzung von printf() ausgegangen
wären.  (avr-libc bietet ja durchaus genügend Alternativen, wenn man
kein printf() haben will oder kann.)

von (prx) A. K. (prx)


Lesenswert?

W.S. schrieb:
> Der TO hat sich an for(;;) gestoßen - und zu Recht.
> Formal ist das nicht falsch, aber es ist unleserlich,

Ein lächerlicher Streit. Wird durch Wiederholung nicht besser.

> Die früher eventuell gewesene Notwendigkeit, selbst etwas zum Optimieren
> beizutragen, ist heutzutage nur noch ein Beitrag zur Unleserlichkeit.

Korrekt.

von (prx) A. K. (prx)


Lesenswert?

Jörg W. schrieb:
> Yep, und damit bist du komplett festgenagelt auf die Ausgabekanäle,
> wie sie in den Sprachumfang gegossen worden sind.

Sprachen mit in der Sprache selbst fest integrierten Ausgabemethoden 
dürften sämtlich aus der Zeit von Batch- oder Commandline-Programmierung 
stammen. In anderen Umgebungen sind diese Elemente weitgehend obsolet.

: Bearbeitet durch User
von Nop (Gast)


Lesenswert?

W.S. schrieb:
> Im übrigen gilt das in entsprechender Form auch für die albernen
> uint32_t Masche.

Das ist keine Scharlatanerie, sondern auf allen System ein 32bit breiter 
unsigned int. Es interessiert niemanden, wie genau das umsetzt, außer 
Leuten, denen die Praxis sowieso wurscht ist und die nur akademisch 
meckern wollen. Aus der Ecke kam Pascal, deswegen ist das ja auch 
dermaßen verfrickelt und fragmentiert, weil man versuchen wollte, das 
nachträglich irgendwie praktisch erträglich zu machen.

Und sowas wie "uint_fast_8t" kennt Pascal ja nichtmal. Weil es keine 
Systemprogrammiersprache ist. Daß Du die innere Logik von C schlichtweg 
nicht teilen magst, führt Dich zu dem Fehlschluß, sie existiere nicht.

> Nun ja, deine Erfahrungen mit Pascal sehen ausgesprochen steinalt aus -
> das ist etwa so, als wenn du heutzutage über K&R-syntax räsonniertest.

Wie ich schon sagte, was glaubst Du denn, wieso es in Pascal 
(stellenweise..) heute sowas wie Pchar gibt. Endlich mal vernünftige 
Strings. Und die Pascal-Erweiterungen sind ja schön, nur leider hat es 
sich in lauter inkompatible Dialekte fragmentiert, das war auch in den 
90ern schon so.

> In C hat man es ja nicht mal geschafft, mit Integertypen aufzuräumen
> UND Zeichentypen (char) von numerischen Typen zu trennen.

Das ist auch gut so, weil ich es relativ häufig habe, daß ich numerische 
Zahlen in der Ausgabe auf Buchstaben mappen muß, und das geht mit 
Idiomen wie "my_number + 'a'" ganz wunderbar.

> Ich halte das für eine kreuzgefährliche Grundeinstellung. Bieder und
> in einfach gehaltener Quelle zu schreiben und das Optimieren dem
> Compiler  zu überlassen, ist also manchem unerträglich.

Ich habe Dir recht detailiert auseinandergesetzt, was mich an Pascal 
gestört hat (18.10.2016 22:33), also tu nicht so, als gehe es um Freude 
am Risiko. Jedesmal, wenn die Rigidität der Sprache mich behindert hat 
und den Quelltext unübersichtlicher gemacht hat, habe ich über dieses 
Müsli geflucht.

Im Grunde kann man das aber pascal auch nicht vorwerfen, weil Pascal als 
Spielzeugsprache für Lehrzwecke konzipiert worden ist.

von Jobst Q. (joquis)


Lesenswert?

W.S. schrieb:
> Ähemm... dann verrate mir doch mal, wie strcat und Konsorten einen
> String an einen anderen dranhängen - per magischem Endpunktfinden?  ;-)

Und du kannst uns mal verraten, mit welchem Trick in Sprachen,die bei 
Strings die Länge immer mit sich führen, diese Längen aus dem Nichts 
gezaubert werden.

Mit stpcpy bzw stpncpy kann man übrigens Strings aneinanderhängen ohne 
dass  es strlen()benötigt. Das Ende und damit die Länge ergibt sich aus 
dem Kopiervorgang.

von Nop (Gast)


Lesenswert?

A. K. schrieb:
> Korrekt. Aber angesichts der Häufigkeit, wie der mittlerweile
> Sicherheitsprobleme durch buffer overflows auftreten, fände ich etwas
> mehr CPU für diesen Zweck eine sinnvolle Investition.

Wenn man, mal salopp gesagt, jeden Zugriff erstmal prüfen wollte (auch 
auf arithmetische Überläufe am besten noch und so), dann werden aus 
jedem Zugriff zwei Zugriffe und ein Vergleich. Da Speicher aber heute 
sowieso schon den Flaschanhals darstellt, wäre das einfach keine Option.

Man stelle sich mal vor, ein ganzes Betriebssystem wäre so lahm wie 
Eclipse. Na prost Mahlzeit, da kann man die Serverfarmen mal eben 
vervierfachen.

Und schon gar nicht embedded, wo man nicht einfach mal eben so 3 Euro 
mehr für einen stärkeren Controller ausgeben mag - in Märkten, wo es 
teils um Centbeträge geht.

Nee, das eigentliche Problem ist, daß zwar jeder von Kapselung und so 
spricht, das aber nur auf Code-Ebene meint. Auf Systemebene bauen wir 
uns (insbesondere mit IoT) aber das genaue Gegenteil, ein totales 
Spaghettikonzept, was aus demselben Grund in die Hose gehen muß wie 
Spaghetticode im kleineren Maßstab auch schon. Eine darartige 
Komplexität ist nicht beherrschbar, das wird man vom Machbarkeitswahn 
mal runterkommen müssen.

von (prx) A. K. (prx)


Lesenswert?

Nop schrieb:
> Da Speicher aber heute
> sowieso schon den Flaschanhals darstellt,

In der Zugriffszeit ja, weniger vom Durchsatz her. Daumenregel: Zugriff 
auf direkt benachbarte Speicherstellen ist sehr günstig, Zugriff auf 
weit entfernte teuer.

Der eigentliche Code von Checks ist relativ billig, sobald die nötigen 
Daten in Registern oder im L1-Cache vorliegen. Highend-CPUs (hab noch 
kein Eclipse auf einem AVR gesehen ;-) haben dafür genug Ressourcen, und 
Operationen, die keine Abhängigkeiten produzieren, sind dementsprechend 
günstig.

Index/Range-Checks müssen auch nicht unbedingt bei jedem Zugriff 
stattfinden, selbst wenn die Sprache das dem Prinzip nach vorsieht. Denn 
solche Operationen können mitunter vom Compiler aus Schleifen 
rausoptimiert werden.

Schlussendlich gilt die alte Regel von Optimierungen: Die weitaus 
meisten Codeteile kommen praktisch ohne sie aus, nur bei den Hotspots 
sind sie wirklich interessant. Für die Sicherheit gilt das freilich 
nicht, weshalb Checks an anderen Stellen als den Hotspots für die 
Performance wenig relevant sind.

von c-hater (Gast)


Lesenswert?

A. K. schrieb:

> Gib dem gleichen Programmierer mehr Geld und er wird besser?

Das nicht. Aber: Gib dem gleichen Programmierer mehr Zeit und er (bzw. 
seine Produkte) werden besser. Aus Sicht der Chefetage wird er dadurch 
aber auch nur teuerer. DAS ist das eigentliche Problem...

Diesem Dilemma haben wir ALLES zu verdanken, was wie heute haben.

Insbesondere Programme, die für winzigste Funktionalitäten MB-weise 
Speicher und auf GHz-Maschinen ganze Sekunden Rechenzeit benötigen und 
die die meiste Zeit damit beschäftigt sind, irgendwelche Fehler zu 
produzieren, zu denen sie nicht einmal eine auf die tatsächliche Ursache 
des Fehlers hinweisende Fehlermeldung liefern können. Exceptionhandler 
ganz oben, ick hör dir trappsen...

Noch höhere Hochsprachen und noch agilere Entwicklungsmethoden sollen 
die Antwort darauf sein. Da lachen doch die Hühner...

Aber die Cheffes glauben nur zu gern diesen Bullshit der 
Vertriebsdroiden...

von Walter S. (avatar)


Lesenswert?

W.S. schrieb:
> Dort findest du bei jeder Stringfunktion ein oder
> mehrmaliges Aufrufen von strlen.
>
> Bevor du also hier von Anfängern schwafelst, solltest du dich besser
> zuvor mal richtig informieren.

dem zweiten Satz kann ich zustimmen,
du solltest ihn aber auch selber anwenden, dann käme nicht so ein 
falscher Satz wie der erste zustande

von Konstantin F. (Firma: "Konniemara") (konstantin-2)


Lesenswert?

>Das muß ein Schüler der C-Programmiersprache eben auswendig lernen. Er
>muß dazu sich eben dran gewöhnen, daß es an vielen Stellen in C "eben so
>ist wie es ist, basta!".

>write(A:9:3, B:y*3:y);

Das sagt mir z.B. gar nichts wenn ich nicht eingearbeitet bin - 
zumindest nicht mehr als ein Formatstring einem c Neuling.
Ist es nicht immer so, dass man neue Sachen auswendig lernen muss wenn 
sie neu sind?
So eine überlegene Selbsterklärende Logik ist da für mich nicht hinter.
Ich kann wirklich kein Pascal. Write schreibt auf einen Kanal.
Den Bildschirm oder eine Datei oder eine Uart?

Was da wie formatiert wird ist absolut unlogisch wenn man nicht einiges 
gelernt, d.h. auswendig gelernt hat.
Leuchtet das nicht ein?

Es sind sich ja nun wirklich alle einig, dass c nicht unbedingt der 
Weisheit letzter Schluss ist, wägen aber auch Vor- und Nachteile ab.
W.S., du hast zwar oben behauptet du würdest nichts verteufeln o.ä, aber 
das machst du nun mal unterschwellig eben doch.

von Chris D. (myfairtux) (Moderator) Benutzerseite


Lesenswert?

for(;;) finde ich persönlich nicht so schön wie while(1) - aber das ist 
wirklich Geschmackssache.

Meine Erfahrung mit C ist, dass man damit durchaus leserlichen Code 
schreiben kann - wenn man nicht meint, alle Gimmicks gleichzeitig nutzen 
zu müssen.

Ich schreibe mittlerweile lieber fünf ausführliche Zeilen als eine Zeile 
engen Programmcode, gerne auch mit ein paar Klammern mehr als nötig.

Dem Compiler ist es vollkommen egal und ich habe damit die besten 
Erfahrungen gemacht - auch bezüglich der Kommentierung.

Stringverarbeitung mit Endmarker hat Vor- und Nachteile. Wer möchte, 
dass die Strings sich die Länge merken, kann problemlos eine 
entsprechende Ersatzbibliothek einbinden.

Aber: er muss es nicht. Man hat die freie Wahl.

Exzessive und insbesondere zeitkritische Stringverarbeitung ist mir im 
Bereich der µCs noch nicht begegnet. Meist landen die Strings eh im 
Flash.
Ich hatte hier noch nie den Fall, dass die offizielle string.h nicht 
ausgereicht hätte. Stringverarbeitung ist immer nur ein unbedeutender 
Nebenschauplatz.

Ich mag C für µC. Man sollte den Code halt nicht zu kompakt schreiben.

Mittlerweile mag ich aber noch mehr Tcl auf µC ;-)

: Bearbeitet durch Moderator
von Stefan F. (Gast)


Lesenswert?

Zum Thema IoT:

> Eine darartige Komplexität ist nicht beherrschbar,
> das wird man vom Machbarkeitswahn
> mal runterkommen müssen.

Das hast du meine volle Zustimmung. Vor allem das Smart-Home und die 
tragbaren Körper-Sensoren werden derzeit viel zu früh in Richtung 
Internet gepusht.

von Oliver S. (oliverso)


Lesenswert?

c-hater schrieb:
>
> Noch höhere Hochsprachen und noch agilere Entwicklungsmethoden sollen
> die Antwort darauf sein. Da lachen doch die Hühner...

All das wurde im wesentlichen deshalb erfunden, um von der Abhängigkeit 
einzelner Programmierer mit Herrschaftswissen weg zu kommen. Ok, der 
Erfolg ist durchwachsen...

Oliver

von Pascalfan (Gast)


Lesenswert?

Nop schrieb:
> Und außerdem wird man bei längeren Texten, wo man überhaupt solche
> strlen-Probleme hat, auch in Pascal letztlich auf ein größeres
> char-Array zurückgreifen, weil Pascalstrings für die Länge nur ein Byte
> haben, also 255 Zeichen zulassen.

Den Scheiß den Du hier über Pascalstrings erzählst kann man sich ja 
nicht mehr mit anhören.
Ab Delphi 2.0 hat Borland einen neuen dynamischen Stringtyp ein geführt, 
der sich vom klassischen Pascalstring dadurch unterscheidet, daß er eben 
keine Längenbegrenzung auf 255 Zeichen hat. In diesem String ist der 
Zähler für die Stringlänge 32Bit lang. Demzufolge kannst Du damit 2^32 
Zeichen (entspricht 4GB) in einem String speichern, was auch Deinen 
Ansprüchen bei weitem genügen sollte. Ja und man sollte es kaum glauben 
das selbst in diesen String am Ende das Nullzeichen angehängt wird, 
obwohl es auf Grund des Zähler eigentlich nicht gebraucht wird. Warum 
man das macht kann ich nicht sagen, es interessiert mich schlichtweg 
auch nicht. Wichtig ist für mich das ich mit dem Datentyp "string" 
einfach und effizient arbeiten kann und zum effizienten Arbeiten gehören 
für mich so einfache Sachen wie z.B. das Verbinden das Verbinden von 
Strings, was ja in Pascal bekanntermaßen durch einfache Addition von 2 
Strings oder auch Chars gemacht wird. Ich brauche mich nicht darum zu 
kümmern ob der Speicher (Puffer) ausreicht, das erledigt letztendlich 
Compiler für mich und das ist auch gut so. Um so einen Kram möchte ich 
mich nicht kümmern müssen, diese Zeit und den erforderlichen Schmalz 
stecke ich lieber in die Umsetzung der Programmieraufgabe.
Du solltest vielleicht mal ein Buch über Objectpascal zur Hand nehmen. 
Dort sind die Innovationen die zwischenzeitlich in Pascal Einzug 
gehalten haben meist sehr gut beschrieben - auch für resistente 
C-Programmierer. Und damit Du mich nicht gleich so dumm anmachst wie 
z.B. Zeno, hier gleich mal eine Quellenangabe : "Windowsprogrammierung 
mit Borland Delphi" von Hans-Peter Kalb - dies mal nur als eine Quelle. 
Dort ist ab S.26ff der Aufbau des neuen Pascalstrings hinreichend gut 
beschrieben. Ansonsten sind die von Borland bis Delphi 7 mitgelieferten 
Handbücher sehr gute Quellen des Wissens.

Ach und dann sprichst Du in Deiner unendlichen Arroganz bei Pascal vom 
betreuten Programmieren - wie überheblich. Pascal oder besser 
Objectpascal wurde so um die Jahrhundertwende recht viel in den Firmen 
eingesetzt, weil zu diesem Zeitpunkt mit der Delphi IDE eine vernünftige 
IDE zur Verfügung stand mit der man schnell und effizient Programme mit 
GUI entwerfen konnte. Dank des in Objectpascal vorhandenen 
Exceptionhandlings war zudem auch eine effektive Fehlerbehandlung 
möglich, die man bei Programmen mit GUI oder auch Programmen welche viel 
mit Dateien arbeiten auch benötigt, weil man eben nicht, wie Du wieder 
mal mit einer nicht zu toppenden Arroganz behauptest, Fehler von 
vornherein vermeiden kann. Programme die mit 90% Userinteraktion 
arbeiten sind halt schon etwas anderes als ein 32kB großes µC Programm, 
welches im wesentlichen autark arbeitet und wo sich Interaktion mit dem 
Menschen auf das Drücken einiger klar definierter Knöpfchen beschränkt.
Und weil das so ist braucht man für PC Programmierung halt Werkzeuge die 
einem die einem solche Sachen wie Objecte und Exceptions bereitstellen 
und das wird in aller Regel nicht C sein weil dieses selbiges nicht 
kennt. Für sowas müßte man schon sowas wie C++ nehmen und auch da wird 
keiner mehr irgendwelche Verrenkungen machen und irgendwelchen kruden 
Code einhacken, sondern man greift da auf Bibliotheken zurück und 
benutzt - soweit es möglich - die dort zur Verfügung gestellten Objecte.

Der Pascalfan

PS: Es ist schon erstaunlich wie lange man bloß wegen einer Frage zu 
for(;;) auf einem teils bedenklichen Niveau diskutieren kann.

von Jobst Q. (joquis)


Lesenswert?

W.S. schrieb:
> C ist bekanntermaßen in weiten Teilen nicht logisch aufgebaut, es fehlen
> Basismittel wie z.B. ein Boolean-Datentyp und vieles mehr, also wird das
> per ordre de mufti erledigt.
> Das muß ein Schüler der C-Programmiersprache eben auswendig lernen. Er
> muß dazu sich eben dran gewöhnen, daß es an vielen Stellen in C "eben so
> ist wie es ist, basta!".

Du verwechselst Logik mit deinen Erwartungen, die du mit anderen 
Sprachen festgelegt hast. C ist mit die in sich logischste und 
konsistenteste aller Programmiersprachen, das ist auch ein Grund für 
ihren Erfolg.

Bei C muss man sehr wenig auswendig lernen, aber man muss sie verstehen. 
C hat die wenigsten Schlüsselworte (von Forth mal abgesehen) und trennt 
klar zwischen Sprachbestandteilen und Funktionen (in Librarys).

Dass man in C auch ohne Boolean-Datentyp alles machen kann, zeigt doch 
nur, dass Boolean als Datentyp überflüssig ist. Für den Fall, dass man 
viele Booleans kompakt speichern will, gibt es Bitfelder.

von Oliver S. (oliverso)


Lesenswert?

Pascalfan schrieb:
> Und weil das so ist braucht man für PC Programmierung halt Werkzeuge die
> einem die einem solche Sachen wie Objecte und Exceptions bereitstellen
> und das wird in aller Regel nicht C sein weil dieses selbiges nicht
> kennt.

Ach je, das Argument kam jetzt zum hundertsten Mal alleine in diesem 
Thread, und es wird dadurch nicht wahrer. Kein Mensch programmiert 
PC-Klickibunti-Software in C.

Aber die Welt besteht nicht nur aus PC-KlickiBunti. Da gibt es noch sehr 
viel mehr, sogar sehr viel mehr. Aber egal...

Mit C ist es wie mit Kochgeräten:
Thermomix , Backöfenautomatikprogramme, und was es da sonst noch an 
Küchen"helferlein" gibt, oder einfach ein scharfes Messer.

Letzteres ist bei ungeübter Anwendung gefährlich, man muß tatsächlich 
lernen, damit umzugehen. Wenn man es aber kann, ist es unschlagbar 
schnell und flexibel.

Trotzdem gibt es auch in der Sterneköche Anwendung für Küchenmaschinen.

Oliver

von Chris D. (myfairtux) (Moderator) Benutzerseite


Lesenswert?

Pascalfan schrieb:
> Der Pascalfan
>
> PS: Es ist schon erstaunlich wie lange man bloß wegen einer Frage zu
> for(;;) auf einem teils bedenklichen Niveau diskutieren kann.

Erstaunlich ist auch, dass Leute die einfachen Forenregeln und auch 
ihren verwendeten Nicknamen vergessen.

Ich möchte Dich also bitten, in Zukunft in diesem Thread wieder als der 
aufzutreten, der Du vorher warst - nämlich "Zeno".

Dann können die anderen die Texte auch im Zusammenhang mit dem vorher 
von Dir Geschriebenen einordnen.

Danke.

von Tasg (Gast)


Lesenswert?

C ist vielleicht aus Sicht eines Elektrotechnikers "logisch". Aus der 
Sicht eines Mathematikers ist Haswell "logisch" und aus der Sicht eines 
Informatikers eher etwas aufgeräumtes wie z.B. C# oder Java. Im 
Endeffekt ist es Geschmackssache.

C ist die Programmiersprache, die am nähesten an der Hardware dran ist. 
Noch näher ist dann tatsächlich nur noch mehr Assembler, aber ab da 
wirds dann wahrscheinlich selbst den Elektrotechnikern zu bunt.

Das hat den schönen Nebeneffekt, dass Programme die in C geschrieben 
wurden, wenn man es richtig macht, am effizientesten sind. Dazu schreibt 
man am besten noch zeitkritische Routinen in Assembler und man holt das 
maximale aus seiner Hardware raus.

Nun ist es aber leider so, dass es tausende verschiedene Prozessortypen, 
Betriebssysteme, etc. gibt und nicht jeder die Lust und/oder Zeit hat, 
sich durch 1000-seitige Programmierhandbücher für irgendwelche 
Prozessoren zu wälzen und dann zu überlegen, mit welchem Prozessorbefehl 
ich mein Programm noch schneller machen kann. Manche bzw. viele Menschen 
wollen einfach nur eine Programmiersprache, mit der man schnell und 
sauber ans Ziel kommt, und das geschriebene dann auf möglichst vielen 
verschiedenen Platformen läuft. Für Mikrocontroller gibt es sowas 
derzeit leider noch nicht. Da man hier alles in C programmiert muss man 
wirklich leider immer alles neu programmieren.

Glücklicherweise gibt es aber ja mittlerweile tausende verschiedene 
Programmiersprachen, wo dann auch für jeden etwas dabe ist: 
Elektrotechniker, Informatiker, Mathematiker, Hausfrauen, Kinder, 
Rentner, Hipster, Betriebswirte, etc

von manoman (Gast)


Lesenswert?

Chris D. schrieb:
> for(;;) finde ich persönlich nicht so schön wie while(1) - aber das ist
> wirklich Geschmackssache.

Es ist Geschmackssache, trotzdem ist es gegen die Philosophie von C.

C wurde erdacht als Hardware unabhängiger Assembler Sprache, die, so wie 
von Assemblern gewohnt, genau das macht was der Programmierer schreibt.

while(1) sagt dem Compiler erzeuge folgenden Maschinencode:

lade Register mit 1
Registertest
bedingter Sprung

for(;;) sagt dem Compiler, erzeuge keinen Maschinencode sondern benutze 
diese Zeile als Rücksprung Adresse für die Schleife.

Unumwunden, als ich mein erstes Berkeley C auf zwei 8 Zoll Disketten in 
die Hände bekam, wurde while(1) als Schwachsinn angesehen.

von (prx) A. K. (prx)


Lesenswert?

Pascalfan schrieb:
> Warum man das macht kann ich nicht sagen,

Aufruf von APIs/DLLs mit C Konvention.

von Nop (Gast)


Lesenswert?

Pascalfan schrieb:

> Ab Delphi 2.0 hat Borland

Lesen ist nicht Deine Stärke, ne? Borland hat.. das ist bereits FAIL. 
Weil es genau zu den proprietär und zu nichts kompatiblen Frickeleien am 
Sprachstandard vorbei zählt, deretwegen Pascal als Sprache so 
fragmentiert geworden ist!

In C kann ich dasselbe Programm (abzüglich der Hardwarelayer) unter 
Windows, unter Linux und auf dem Mikrocontroller laufen lassen. Und Du 
kommst mit "Delphi unter Windows" an. Na super.

Abgesehen davon würde ich für komplexe GUI-Projekte weder C noch Pascal 
verwenden, aber das nur am Rande.

Nebenbei, gewöhn Dir mal Absätze an. Wenn Du im selben Stil so 
strukturlos programmierst wie Du schreibst, wundert es mich nicht, daß 
Du betreutes Programmieren brauchst.

von Rolf Magnus (Gast)


Lesenswert?

A. K. schrieb:
> Gib dem gleichen Programmierer mehr Geld und er wird besser?

Nein. Eher: Suche dir bessere Programmierer und nimm die, auch wenn sie 
teurer sein mögen. Wenn man immer den billigsten nimmt und Lohndumping 
betreibt, bekommt man eben auf Dauer auch das, was man bezahlt.
Das heißt nicht, dass billige Programmierer grundsätzlich schlecht wären 
und teure grundsätzlich gut, sondern nur, dass Sparwahn auch 
Konsequenzen hat. Das sieht man auch immer beim regelmäßigen Gejammer 
über angeblichen Fachkräftemangel. Meist sind genug Fachkräfte 
vorhanden, nur eben keine, die ihre Arbeitskraft für das Geld verkaufen 
wollen, das die Industrie bietet.

W.S. schrieb:
> Bevor du also hier von Anfängern schwafelst, solltest du dich besser
> zuvor mal richtig informieren. Der Punkt ist, daß irgendwelche
> sogenannten Stringfunktionen eben keinen tatsächlichen Stringtyp
> ersetzen können. Sowas muß in die Sprachdefinition eingebaut sein und
> der Compiler muß das selber handhaben - SELBER! verstehst du das?

Du weißt aber, dass er das im Falle von GCC auch tut? Hier eine Liste 
der im Compiler eingebauten Standardfunktionen:
https://gcc.gnu.org/onlinedocs/gcc-6.2.0/gcc/Other-Builtins.html#Other-Builtins
Soviel dazu, sich erstmal zu informieren.

> Im übrigen gilt das in entsprechender Form auch für die albernen
> uint32_t Masche. Solange der Compiler SELBST keine anderen Datentypen
> kennt als int mit den Geschmacksrichtungen long, short, unsigned,
> signed, so lange ist das Zusammenschreiben irgendwelcher Headerdateien
> nichts als Brimborium und Scharlatanerie.

Und wieder nur blödes Gelaber ohne irgendwelche Begründung...
Den Rest des Postings, der auch wieder nur die gleichen unbegündeten und 
unsinnigen Behauptungen wiederholt, C sei unlogisch, hab ich einfach mal 
entsorgt. Kommt eh nichts neues drin vor.

W.S. schrieb:
> Erstens: nimmt der Compiler die völlig variable Latte an all den
> Parametern selbst auseinander und zerlegt sie in all das, was gebraucht
> wird,
>
> Zweitens: läßt er logischerweise all die Funktionen weg, die konkret
> nicht gebraucht werden

Das hat C++ mit seinen Stream-Operatoren auch hinbekommen, ganz ohne 
dass man das im Sprachkern einbauen hätte müssen.

> Drittens kann er auch mit variablen Formatangaben zurechtkommen (also
> sowas wie write(A:9:3, B:y*3:y);

Aha, und das soll man ganz ohne Vorwissen lesen können? Bei C beschwerst 
du dich ja darüber, dass man das nicht kann.

> Die Chance zu sowas sehe ich alledings zu null an. In C hat man es ja
> nicht mal geschafft, mit Integertypen aufzuräumen UND Zeichentypen
> (char) von numerischen Typen zu trennen.

Eine Trennung wird nicht erzwungen, aber es gilt die Regel: char für 
Text, signed und unsigned char zum rechnen. Wenn man diese einfache 
Regel beachtet, ist es auch nicht anders. Ich gebe aber zu, dass diese 
Regel offenbar viele nicht kapieren, oder sie denken zu viel darüber 
nach und meinen, schlauer als der Compiler sein zu müssen - mit 
zweifelhaftem Erfolg. Mir wäre auch lieber, wenn mit char nicht 
gerechnet werden könnte und man explizit in einen Typ "byte" oder so 
konvertieren müsste, um daraus einen Integer zu bekommen. Das im 
Nachhinein einzuführen, würde aber sehr viel bestehenden Code 
inkompatibel machen.

W.S. schrieb:
> A. K. schrieb:
>> Nur sind Logik und Brauchbarkeit nicht deckend.
>
> Das ist allen verständnisvollen Programmierern völlig klar. Es geht ja
> auch nicht darum hier irgendwas zu verteufeln, sondern es geht darum,
> die Sache einfach nur nüchtern beim Namen zu nennen und dabei auch mal
> deren Grenzen aufzuzeigen.

Dann solltest du damit mal anfangen.

> Der TO hat sich an for(;;) gestoßen - und zu Recht.
> Formal ist das nicht falsch, aber es ist unleserlich, denn wir sind
> Menschen und keine Maschinen.

Ich habe überhaupt kein Problem damit, es zu lesen und zu verstehen, und 
das, obwohl ich keine Maschine bin. Was mache ich falsch?
Jedenfalls ist irgendein goto-Gefrickel erheblich schlechter lesbar. Ich 
würde auch nicht erwarten, dass bei einem goto das Sprunglabel irgendwo 
vor dem goto selbst ist. Das ist einfach nur Spaghetticode, wie man ihn 
in den 80ern des letzten Jahrhunderts mal auf Home-Computern in BASIC 
verbrochen hat.

>> Ich suche ein Zeichen, und wenn es nicht gefunden wird, muss ich diesen
>> Fall eh separat behandeln.
>
> Nicht immer. ZB wenn man über den Punkt die Erweiterung eines
> Dateinamens sucht. Wenn kein Punkt dabei ist, hat er keine Erweiterung
> und der Leerstring ist korrekt.

Naja, da heute selbst unter Windows mehrere Punkte in einem Dateinamen 
möglich sind, muss man sowieso weitersuchen, bis man den letzten Punkt 
gefunden hat. Ich muss also erstmal so lange suchen, bis nichts mehr 
gefunden wurde und danach das Ergebnis vom vorherigen Suchlauf nehmen, 
sofern vorhanden.

>> Im übrigen kann man mit strchr auch explizit nach dem \0 selbst suchen.
>> Ob man das braucht, sei mal dahingestellt, aber es ginge nicht, wenn
>> dessen Adresse auch dann zurückgegeben würde, wenn das gesuchte Zeichen
>> gar nicht gefunden wird.
>
> In C hat jeder String eine \0 und die wird auch von meiner Funktion
> gefunden.

Wie machst du dann die Unterscheidung?

Pascalfan schrieb:
> Wichtig ist für mich das ich mit dem Datentyp "string" einfach und
> effizient arbeiten kann und zum effizienten Arbeiten gehören für mich so
> einfache Sachen wie z.B. das Verbinden das Verbinden von Strings, was ja
> in Pascal bekanntermaßen durch einfache Addition von 2 Strings oder auch
> Chars gemacht wird. Ich brauche mich nicht darum zu
> kümmern ob der Speicher (Puffer) ausreicht, das erledigt letztendlich
> Compiler für mich und das ist auch gut so.

Auf dem PC ja. Auf einem kleinen 8-Bitter wäre das recht verheerend, 
wenn im Hintergrund ständig neu Speicher für die Ergebnisse dieser 
Operationen allokiert würde.

> PS: Es ist schon erstaunlich wie lange man bloß wegen einer Frage zu
> for(;;) auf einem teils bedenklichen Niveau diskutieren kann.

Ich finde das nicht weiter tragisch. Die ursprüngliche Frage ist 
beantwortet, und die Diskussion hat sich danach in eine andere Richtung 
entwickelt. Ich sehe keinen Schaden darin, weiter zu diskutieren.

von besucher47 (Gast)


Lesenswert?

Nop schrieb:
>Abgesehen davon würde ich für komplexe GUI-Projekte weder C noch Pascal
>verwenden, aber das nur am Rande.

gerade Pascal ist dafür (am besten) geeignet
(siehe Lazarus, oder firemonkey jenachdem)

Pascal für AVR usw. gibt es auch..

tortzdem wird man für den µC  "C" verwenden, aber nicht weil die Sprache 
"C" besser ist...

von Jobst Q. (joquis)


Lesenswert?

Rolf Magnus schrieb:
>>> Im übrigen kann man mit strchr auch explizit nach dem \0 selbst suchen.
>>> Ob man das braucht, sei mal dahingestellt, aber es ginge nicht, wenn
>>> dessen Adresse auch dann zurückgegeben würde, wenn das gesuchte Zeichen
>>> gar nicht gefunden wird.
>>
>> In C hat jeder String eine \0 und die wird auch von meiner Funktion
>> gefunden.
>
> Wie machst du dann die Unterscheidung?

Was muss da unterschieden werden? Wenn man mit strchr das Nullbyte 
sucht, sucht man das Ende des Strings und da jeder String mit \0 beendet 
wird, gibt es den Fall "nicht gefunden" garnicht, bei dem strchr NULL 
herausgeben würde. Übrigens gibt es in der GNU-CLib inzwischen auch 
strchrnul, das sich genauso verhält wie meine Funktion mstrchr.

von besucher47 (Gast)


Lesenswert?

>da jeder String mit \0 beendet
>wird,

das ist doch das Problem
diese Annahme..

verwendet (irgendjemand) den code dann irgendwann mal z.b in einer 
Library
und ein "Böser bube" von extern ruft den Code auf, hat der String halt 
mal keine \0 mehr...

von temp (Gast)


Lesenswert?

Pascalfan schrieb:
> Wichtig ist für mich das ich mit dem Datentyp "string"
> einfach und effizient arbeiten kann und zum effizienten Arbeiten gehören
> für mich so einfache Sachen wie z.B. das Verbinden das Verbinden von
> Strings, was ja in Pascal bekanntermaßen durch einfache Addition von 2
> Strings oder auch Chars gemacht wird. Ich brauche mich nicht darum zu
> kümmern ob der Speicher (Puffer) ausreicht, das erledigt letztendlich
> Compiler für mich und das ist auch gut so. Um so einen Kram möchte ich
> mich nicht kümmern müssen, diese Zeit und den erforderlichen Schmalz
> stecke ich lieber in die Umsetzung der Programmieraufgabe.

Das gilt für den PC oder Controller mit genügend RAM und/oder 
vernünftiger Speicherverwaltung. Auf kleineren embedded Systemen kann 
das verdammt schnell in die Hose gehen. Wenn das Programm dann nicht 
mehr das macht was es soll weil es keine 100Byte Speicher mehr am Stück 
für den String kriegt hat obwohl in der Summe noch genügend da ist. Und 
wenn das dann auch noch davon abhängig ist in welcher Reihenfolge die 
vorausgegangenen Speicheranforderungen kamen wird es komplett 
undurchsichtig. Dabei kann dir aber auch kein Compiler helfen, egal ob C 
oder Pascal. Am Ende ist es besser man kümmert sich da selbst drum als 
das man hofft es wird schon irgendwie gehen.

Bei der PC-Programmierung ist es heute eh der Fall, dass sich niemand 
mehr um den Speicher Gedanken macht. Und auch nicht darum innere 
Schleifen darauf hin zu Optimieren, die Anzahl von Speicheranforderungen 
und Freigaben zu reduzieren. Gerade bei Strings sind die klassische 
C-Methoden in engen zeitkritischen Schleifen teilweise 10er Potenzen 
schneller als in Hochsprachen. Wenn eine fiktive substr()-Funktion erst 
mal Speicher anfordern muss um dann einen Teil des Strings zu kopieren, 
kann's nicht mehr schnell gehen. Klar würde es auch da Wege geben das 
elegant zu lösen. Das Problem ist nur, keiner weiß wie die interne 
Implementierung der Strings in Pascal o.ä. wirklich abläuft. Als 
Beispiel mal eine fiktive Aufgabe:
In einer csv-Datei stehen 100Mio Vor- plus Nachnamen. Die soll in eine 
2. Datei kopiert werden, allerdings nach Nachnamen sortiert. Wenn jetzt 
die ach so gelobte Hochsprache nur für die interne Darstellung 200Mio 
mal 2-50Byte Speicher anfordert und beim Sortieren mit dynamische 
Strings hantiert, hat sie von vornherein gegen eine intelligente 
C-Variante verloren. Klar erfordert das auch Gehirnschmalz und birgt 
Gefahren beim Hantieren mit Pointern. Der Entwickler kann aber selbst 
entscheiden was er wie will. Bei Sprachen die immer und überall mit 
dynamischen Strings arbeiten muss ich erst mal Versuchsreihen machen um 
zu erahnen was intern schnell und was langsam geht.

von Jobst Q. (joquis)


Lesenswert?

besucher47 schrieb:
>>da jeder String mit \0 beendet
>>wird,
>
> das ist doch das Problem
> diese Annahme..
>
> verwendet (irgendjemand) den code dann irgendwann mal z.b in einer
> Library
> und ein "Böser bube" von extern ruft den Code auf, hat der String halt
> mal keine \0 mehr...

In C wird jeder String mit \0 beendet. Wenn ein "böser Bube" den C-Code 
in einer andern Sprache verwendet, kann natürlich nichts garantiert 
werden.

Aber ich muss mich korrigieren. Je nach Implementation kann strchr mit 
\0 aufgerufen auch immer NULL zurückgeben. Dann ist es nicht geeignet, 
um das Stringende zu suchen. Mit strchrnul geht das.

von (prx) A. K. (prx)


Lesenswert?

Es wird nominell jeder String mit \0 beendet. Aber es wird nicht 
automatisch jedes char-array mit \0 beendet, in dem ein Haufen Zeichen 
liegen, die ein String sein sollen. Bei
   char s[10];
   strncpy(s, "0123456789abcdef", sizeof s);
liegt kein \0 drin, und bei strlen(s) wird es dann interessant.

: Bearbeitet durch User
von Tasg (Gast)


Lesenswert?

A. K. schrieb:
> Es wird nominell jeder String mit \0 beendet. Aber es wird nicht
> automatisch jedes char-array mit \0 beendet, in dem ein Haufen Zeichen
> liegen, die ein String sein sollen. Bei
>    char s[10];
>    strncpy(s, "0123456789abcdef", sizeof s);
> liegt kein \0 drin, und bei strlen(s) wird es dann interessant.

Was wird interessant? Das Programm stürzt bestenfalls ab. Alleine die 
Tatsache, dass so etwas überhaupt möglich ist, spricht gegen C.

von Nop (Gast)


Lesenswert?

A. K. schrieb:
> strncpy(s, "0123456789abcdef", sizeof s);
> liegt kein \0 drin, und bei strlen(s)

Offensichtlich ist Dir ja klar, daß die nicht-n-Funktionen heikel sein 
können, deswegen nimmst Du zurecht strncpy? Wieso nimmst Du dann aber 
nicht auch strnlen?

von temp (Gast)


Lesenswert?

A. K. schrieb:
> Es wird nominell jeder String mit \0 beendet. Aber es wird nicht
> automatisch jedes char-array mit \0 beendet, in dem ein Haufen Zeichen
> liegen, die ein String sein sollen. Bei
>    char s[10];
>    strncpy(s, "0123456789abcdef", sizeof s);
> liegt kein \0 drin, und bei strlen(s) wird es dann interessant.

Gutes Beispiel dafür dass nicht immer stncpy der Heilsbringer ist und 
der Einsatz einem davon befreit zu denken. Interessant wird es wenn man 
danach strlen(s) macht und alles erst mal korrekt aussieht. Man wundert 
sich u.U. dann plötzlich warum die Release-Version abschmiert weil 
strlen() plötzlich da liest wo nichts mehr ist...

von (prx) A. K. (prx)


Lesenswert?

Nop schrieb:
> Wieso nimmst Du dann aber nicht auch strnlen?

Weil es strncpy seit Anbeginn von C gibt, strnlen aber noch recht frisch 
ist. Posix kennt das erst in der 2008er Version.

von (prx) A. K. (prx)


Lesenswert?

Jobst Q. schrieb:
> Mit strchrnul geht das.

Steht in keinem Standard. Ist eine GNU Erweiterung.

von temp (Gast)


Lesenswert?

Tasg schrieb:
> Was wird interessant? Das Programm stürzt bestenfalls ab. Alleine die
> Tatsache, dass so etwas überhaupt möglich ist, spricht gegen C.

Die Tatsache dass man mit einem Auto gegen den Baum fahren kann wenn man 
gerade an Handy oder Frau fummelt, spricht eindeutig gegen Bäume am 
Straßenrand. Besser wären Postkutschen, Pferde interessieren sich für 
beides nicht.

von (prx) A. K. (prx)


Lesenswert?

temp schrieb:
> Die Tatsache dass man mit einem Auto gegen den Baum fahren kann wenn man
> gerade an Handy oder Frau fummelt, spricht eindeutig gegen Bäume am
> Straßenrand.

Insbesondere spricht es gegen Airbags. Der Darwin'schen Auslese wegen.

von Quax (Gast)


Lesenswert?

temp schrieb:
> In einer csv-Datei stehen 100Mio Vor- plus Nachnamen. Die soll in eine
> 2. Datei kopiert werden, allerdings nach Nachnamen sortiert.
[...]
> von vornherein gegen eine intelligente C-Variante verloren. Klar erfordert
> das auch Gehirnschmalz und birgt Gefahren beim Hantieren mit Pointern.

Mir ist nicht ganz klar, was das in so einem Fall angemessene Vorgehen 
(externer Mergesort z.B.) generell mit C und Zeigern zu tun hat.

> Wenn jetzt die ach so gelobte Hochsprache nur für die interne Darstellung
> 200Mio mal 2-50Byte Speicher anfordert

Das könnte man in C genauso versuchen wie in einer anderen 
Programmiersprache. Was soll das zeigen?

von (prx) A. K. (prx)


Lesenswert?

Gemeint ist wohl, dass es oft günstiger ist, Pointer auf Daten zu 
sortieren, als die Daten selbst. Allerdings kann man statt Pointern auch 
einen Indexvektor sortieren.

: Bearbeitet durch User
von temp (Gast)


Lesenswert?

Quax schrieb:
> Das könnte man in C genauso versuchen wie in einer anderen
> Programmiersprache. Was soll das zeigen?

A. K. schrieb:
> Gemeint ist wohl, dass es oft günstiger ist, Pointer auf Daten zu
> sortieren, als die Daten selbst. Allerdings kann man statt Pointern auch
> einen Indexvektor sortieren.

Klar der Weg der Hochsprache ist ja: Für jede Zeile einen String und die 
in ein Array. Womit man schon die ersten zig. Mio Speicheranforderungen 
gemacht hat. Nodejs und JavaScript legen sich hierbei schon die Karten. 
Was da in Pascal passiert kann ich nur erahnen. Wenn beim Sortieren noch 
mit Substrings gearbeitet wird, geht der Reigen weiter. Bei bekannter 
Anzahl Zeilen braucht man in C genau 2 Speicheranforderungen. Auf alle 
Fälle aber niemals so viel wie zu sortierende Elemente. Der Rest ist 
reines Pointerhandling. Ist zwar etwas komplexer zu Programmieren aber 
manchmal kommt es eben auf Geschwindigkeit an. Und wir sprechen hier 
nicht von Prozenten sondern von Welten.

von (prx) A. K. (prx)


Lesenswert?

Wie schon vorhin gesagt: Ob du ein Array aus Pointern sortierst, oder 
eines aus Indizes, das schenkt sich wenig.

von besucher47 (Gast)


Lesenswert?

laberts doch nicht immer von Sachen von denen ihr keine Ahnung habt..

ein String in Pascal ist auch ein Pointer, sogar mit Referenzzählung..

von Vlad T. (vlad_tepesch)


Lesenswert?

Pascalfan alias Zeno schrieb:
> Den Scheiß den Du hier über Pascalstrings erzählst kann man sich ja
> nicht mehr mit anhören.
oha - große töne spucken

> Ab Delphi 2.0 hat Borland einen neuen dynamischen Stringtyp ein geführt,
> der sich vom klassischen Pascalstring dadurch unterscheidet, daß er eben

Und dann selbst Äpfel mit Birnen vergleichen.
Alle reden hier von Pascal und du fängst von Delphi/ObjectsPascal an.
Das ist wie c vs c++.
Das sind zwei einfach 2 verschiedene Sprachen.
Das ist als würde ich schreiben
1
Den Scheiß den Du hier über C-"Strings" erzählst kann man sich ja nicht mehr mit anhören.
2
Ab C++ hat Bjarne Stroustrup einen neuen dynamischen Stringtyp 
3
std::string ein geführt, der sich vom klassischen C-"Strings" dadurch 
4
unterscheidet, daß er eben seine Länge speichert. 
5
Ja und man sollte es kaum glauben 
6
das selbst in diesen String am Ende das Nullzeichen angehängt wird, 
7
obwohl es auf Grund des Zähler eigentlich nicht gebraucht wird. Warum 
8
man das macht kann ich nicht sagen, es interessiert mich schlichtweg 
9
auch nicht. Wichtig ist für mich das ich mit dem Datentyp "std::string" 
10
einfach und effizient arbeiten kann und zum effizienten Arbeiten gehören 
11
für mich so einfache Sachen wie z.B. das Verbinden das Verbinden von 
12
Strings, was ja in c++ bekanntermaßen durch einfache Addition von 2 
13
Strings oder auch Chars gemacht wird. Ich brauche mich nicht darum zu 
14
kümmern ob der Speicher (Puffer) ausreicht, das erledigt letztendlich 
15
die Klasse 
16
[Anmerkung: hier stand vorher Compiler - ich bin mir ziemlich sicher, 
17
dass das auch für Objectspascal falsch ist, weil das zur Laufzeit gemacht wird]
18
für mich und das ist auch gut so. 
19
Um so einen Kram möchte ich mich nicht kümmern müssen, 
20
diese Zeit und den erforderlichen Schmalz 
21
stecke ich lieber in die Umsetzung der Programmieraufgabe.
22
Du solltest vielleicht mal ein Buch über C++ zur Hand nehmen. 
23
Dort sind die Innovationen die zwischenzeitlich in C++ Einzug 
24
gehalten haben meist sehr gut beschrieben - auch für resistente 
25
Pascal-Programmierer.

: Bearbeitet durch Moderator
von besucher47 (Gast)


Lesenswert?

>Alle reden hier von Pascal

jeder redet von dem Pascal dass am besten in seine Argumentation passt..

die einen von einem Aktuellen (z.b aktuelle FPC)
die anderen von uralten (warum auch immer)

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


Lesenswert?

besucher47 schrieb:
> jeder redet von dem Pascal dass am besten in seine Argumentation passt

Wer aber mit modernen objektorientierten Pascal-Dialekten argumentiert,
der sollte diese dann auch gegen aktuelle C++-Versionen vergleichen,
damit es nicht Äpfel und Birnen werden.

von Rolf Magnus (Gast)


Lesenswert?

besucher47 schrieb:
>>Alle reden hier von Pascal
>
> jeder redet von dem Pascal dass am besten in seine Argumentation passt..
>
> die einen von einem Aktuellen (z.b aktuelle FPC)

Genau das ist das Problem: "z.B.". Jeder redet von einem anderen Pascal, 
weil es das Pascal nicht mehr gibt, im Gegensatz zu C.
Und wie Vlad schon ausgeführt hat, ist es ziemlich dämlich, Lazarus mit 
C zu vergleichen. Das ist für Pascal das, was C++ für C ist: Eine neue 
Sprache, die darauf aufbaut und weitgehend dazu kompatibel ist, aber 
viele neue Möglichkeiten wie OOP und Exceptions mitbringt.

> die anderen von uralten (warum auch immer)

Weil es ein sinnvollerer Vergleich ist.

von Yalu X. (yalu) (Moderator)


Lesenswert?

Die Diskussion um C und Pascal (eigentlich ja sowieso offtopic, aber
sei's drum) dreht sich ziemlich im Kreis, weil von einigen Leuten Dinge
über einen Kamm geschert werden, die eigentlich separat betrachtet
werden sollten.

Deswegen möchte ich (wahrscheinlich erfolglos ;-)) versuchen, etwas
Ordnung in die Diskussion zu bringen und dabei die vier letzten
Kommentare von Vlad, besucher47, Jörg und Magnus aufgreifen:

1. Pascal und Object-Pascal sind (ähnlich wie C und C++) zwei
   verschiedene Sprachen. Object-Pascal ist zwar der Nachfolger von
   Pascal, deswegen ist aber Pascal noch lange nicht verschwunden. Um
   die Unterschiede klarer hervorzuheben, verwende ich im Folgenden
   die Begriffe "ISO-Pascal" für das prozedurale Pascal, "Object-Pascal"
   für das objektorientierte Pascal und "Pascal-Familie" als Oberbegriff
   für beide zusammen. Entsprechend ist "C-Familie" der Oberbegriff für
   C und C++.

2. Die Argumente werden teils auf PC- und teils auf µC-Anwendungen
   bezogen (wobei mit µC in diesem Zusammenhang einfache Mikrocontroller
   wie der AVR, PIC oder 8051 gemeint sind). Da für PCs und µCs völlig
   unterschiedlich Anforderungen gelten, sollte man diese Argumente
   nicht durcheinanderwürfeln.

Es gibt also sowohl in der C- als auch in der Pascal-Familie Sprachen
mit prozeduraler (C und ISO-Pascal) und solche mit objektorientierter
Ausprägung (C++ und Object-Pascal).

Alle vier Sprachen gibt es sowohl für PCs als auch für kleine µC (wie
AVRs, PICs und 8051er). Die µC-Varianten sind dabei mehr oder weniger
eingeschränkt.

Hier ist eine Übericht der vier Kategorien:

1
      prozedural              objektorientiert
2
—————————————————————————————————————————————————
3
PC    K: PC-PP                K: PC-OOP
4
      C: C                    C: C++
5
      P: ISO-Pascal           P: Object-Pascal
6
      V: vollständig          V: vollständig
7
—————————————————————————————————————————————————
8
µC    K: µC-PP                K: µC-OOP
9
      C: C                    C: C++
10
      P: ISO-Pascal           P: ISO-Pascal
11
      V: leicht abgespeckt    V: stark abgespeckt
12
—————————————————————————————————————————————————

Die einzelnen Einträge der Tabelle bedutet:

K: Kategorie (zur Referenzierung im folgenden Text)
C: Sprache aus der C-Familie
P: Entsprechende Sprache aus der Pascal-Familie
V: Vollständigkeit der Sprachimplementierung

Diese Kategorien sind nicht etwas virtueller Natur, denn für allen vier
sind Compiler bzw. Entwicklungsumgebungen verfügbar. Ein paar Beispiele
(ohne Anpspruch auf Vollständigkeit):

C-Familie:

PC-PP:  GCC, Microsoft Visual C++ (im C-Modus)
PC-OOP: G++, Microsoft Visual C++
µC-PP:  AVR-GCC, IAR C, MikroE mikroC, MPLAB XC8, SDCC
µC-OOP: AVR-G++, IAR C++

Pascal-Familie:

PC-PP:  Free Pascal (im ISO-Modus), GNU Pascal (Entwicklung eingestellt)
PC-OOP: Free Pascal, Delphi
µC-PP:  MikroE mikroPascal, E-LAB AVRco, Turbo51
µC-OOP: Free Pascal für AVR


Es sollte klar sein, dass Compiler bzw. deren Sprachumfang nur innerhalb
einer der vier Kategorien (PC-PP, PC-OOP, µC-PP und µC-OOP) sinnvoll
verglichen werden können.

Damit relativiert sich auch die Diskussion um die verwendeten String-
Typen:

Dynamische Strings (nahezu) beliebiger Länge gibt es ausschließlich in
der Kategorie PC-OOP. Für string-intensive Ausgabestellungen auf dem PC
wird man deswegen sinnvollerweise die objektorientierten Varianten, also
C++ oder Object-Pascal wählen.

Strings in PC-PP, µC-PP und µC-OOP sind statisch, d.h. sie haben zwar
eine variable Länge, aber dennoch eine feste Gesamtkapazität, die bei
der Variablendeklaration festgelegt wird. Ihre Länge wird entweder über
ein Längenbyte (0..255) oder eine Null-Markierung am Ende angegeben. Das
gilt insbesondere auch für Free Pascal auf dem AVR, wo es im Gegensatz
zur PC-Version nur ShortStrings (Char-Array mit Längeninformation im
ersten Array-Element), jedoch keine AnsiStrings (dynamische Strings mit
32-Bit-Längeninformation).

Deswegen kann darüber disuktiert werden, ob die nullterminierten Strings
vonn C oder die ShortStrings von Pascal besser sind. Ebenso können die
C++-Strings mit den AnsiStrings von Object-Pascal verglichen werden.

Der Vergleich von nullterminierten mit AnsiStrings oder von C++-Strings
mit ShortStrings kann aber aus den genannten Gründen überhaupt nicht als
Grundlage für den Vergleich der beiden Sprachfamilien dienen.

Ebenso unsinnig ist es, die Objektorientierung von Object-Pascal als
Vorteil gegenüber C aufzuführen. Denn für jede Plattform, auf der
Object-Pascal läuft, ist auch ein C++-Compiler verfügbar (nur umgekehrt
nicht).

von W.S. (Gast)


Lesenswert?

Jobst Q. schrieb:
> Stringhandling ist die Bearbeitung von Strings beim Lesen und Schreiben.
> Da der String in C nichts anderes ist als ein Zeiger auf den Anfang,

O ha, Strings sind was anderes als Streams. Junge, sowas passiert mir 
selbst dann nicht, wenn ich mal zu tief ins Weinglas geschaut habe...


Jörg W. schrieb:
> Yep, und damit bist du komplett festgenagelt auf die Ausgabekanäle,
> wie sie in den Sprachumfang gegossen worden sind.  Das ist doch genau
> einer der Kritikpunkte an Pascal oben, dass man das, was der Compiler
> bei write[ln] macht, nicht im eigenen Code ebenfalls zur Verfügung
> hat.  Alles, was als Ausgabekanal nicht bereits so ist, dass es von
> der Implementierung als "Datei" betrachtet würde, kann man damit
> vergessen.

Sag mal, wovon redest du eigentlich? "festgenagelt"? Au weia!
write ist die Stream-Ausgabefunktion von str und du hast mit write 
schlichtweg alle im jeweiligen Betriebssystem zugreifbaren Kanäle zur 
Verfügung. Auch stdout, wenn du das magst.

Wie kommst du zu der Aussage, daß man das nicht im eigenen Code hätte?

Ich will mal davon absehen, daß wir hier im "PC-Programmierung"-Forum 
sind, wenn du schon von µC anfängst.

Also könntest du dir deinen String per str in gleicher Weise und 
gleichem Funktionsumfang wie write erzeugen und ihn dann verfrachten, 
wohin du ihn willst.

Der Knackpunkt ist die Frage "Übersetzungsarbeit zur Übersetzungszeit 
oder zur Laufzeit?". Wählt man das erstere, dann muß man's eben entweder 
selbst tun oder es muß in den compiler eingebaut sein, will man's der 
Zielhardware aufbürden, dann muß man eben sowas wie printf wählen - was 
ich aus ideologischen Gründen ablehne: Was man am PC per Compiler 
erledigen kann, sollte man nicht einem µC-Zielsystem überhelfen.

Es ist ja nicht so, daß Pascal für sowas wie printf ungeeignet wäre, es 
gibt seit langem dafür Entsprechungen für Leute, die's nicht lassen 
können. Aber es ist überflüssig, weil man auf dem PC mit str und write 
wesentlich mächtigere Ausdrucksmittel hat - und weil all sowas wie 
printf, write und Konsorten von früher her vorgesehen sind für 
Kommandozeilen-technik und deshalb für moderne GUI-Anwendungen überhaupt 
nicht mehr gebraucht werden.

Auf den µC mache ich das zwecks Vermeidung solchen Overheads so, daß ich 
das, was auszugeben ist, selber separat hinschreibe. Siehe Lernbetty, da 
hab ich sowas vorgeturnt. Das Ergebnis ist, daß es kompakter und 
schneller ist als alle printf-Implementationen.

Also, das Herumgejammer von C-Leuten über write bei pascal finde ich 
ausgesprochen albern - und obendrein würde man es in einer Firmware auf 
einem µC auch in Pascal anders machen als in einem Programm auf einem 
PC. Da sind ja doch wesentliche Unterschiede.


nochwas:
A. K. schrieb:
> Die fehlende
> Unterscheidung ist eine Art Axiom von C, ob man es mag oder nicht.
> ...
> C dafür zu kritisieren, dass es C bleibt, ist also unredlich. Du musst C
> deshalb nicht mögen, aber die Axiome von C sind fixiert.

Tja, ich weiß.

Das Problem steckt dennoch tiefer: C ist derzeit eine Monokultur - 
zumindest in µC-Gefilden. Das ist schlecht, ganz schlecht. Die 
Menschheitsgeschichte sollte es uns unmißverständlich gelehrt haben, daß 
Monokulturen aller Art immer schlecht sind, und uns fehlen mittlerweile 
weitgehend die Alternativen in der Programmierung. Was ähnliches sehe 
ich in der Hardware bei den Cortexen. Jaja, man kann beides derzeit 
trefflich benutzen, das ist gar keine Frage, aber es fehlt die 
Konkurrenz und damit wächst ubiquitär der Kalk - selbst schon in den 
Köpfen von Jungingenieuren. Jetzt kann man Mutmaßungen über den 
Zeitverlauf anstellen und jeder kann sich fragen, ob man noch selbst 
reinschlittert in die zu erwartenden Malessen oder wer in x Jahren 
Rentner oder schon tot ist. Fest steht, DASS es irgendwann mal kracht. 
Ich z.B. will mir garnicht vorstellen müssen, daß ein C wie es 
heutzutage gebraucht wird, in 50 Jahren immer noch in die dann aktuellen 
Cortexe gebrutzelt wird - mit all den Uralt-Lasten aus seiner Steinzeit.

Eigentlich wäre Findigkeit, Innovation und sowas wie Frontrunning hier 
bei uns dringendst vonnöten, denn nur durch sowas können wir den 
Wohlstandsberg so lala aufrechterhalten, auf dem wir derzeit leben. Wenn 
nicht, dann gute Nacht unseren Enkeln. Nun, Innovation geht bei den 
Programmiersprachen nur dann, wenn man entweder eine renovierfähige 
Sprache ausbaut oder eine ganz neue erfindet. Aber mit einer 
renovierunwillgem C-Gemeinde läßt sich das nicht backen.

W.S.

von W.S. (Gast)


Lesenswert?

Yalu X. schrieb:
> Strings in PC-PP, µC-PP und µC-OOP sind statisch, d.h. sie haben zwar
> eine variable Länge, aber dennoch eine feste Gesamtkapazität, die bei
> der Variablendeklaration festgelegt wird.

Yalu, erstmal Dank für deine Bemühungen, in diesen wilden Haufen etwas 
Ordnung bringen zu wollen.

Aber bei PC-PP liegst du falsch. Seit rund 20 Jahren (also seit Win95), 
als Pascal-Compiler für die Win32-Plattform aufkamen, sind die Strings 
dynamisch geworden - das ist die Zeit nach BP7. Ich hab hier immer noch 
ein steinaltes Virtual-Pascal, wo dieses als Standard-String dient. Wenn 
man einen "alten" String haben will, muß man dediziert 'shortstring' 
nehmen.

Ich sehe allerdings ein, daß man auf einem µC in ganz vielen Fällen 
keine bis zu 2 GB großen Strings benötigt.

Aber: Es ist alles drin, vom Kleinsten bis zum schier unendlich großen 
bei Pascalimplementierung für 64Bit Systeme.

W.S.

von Nop (Gast)


Lesenswert?

W.S. schrieb:
> Eigentlich wäre Findigkeit, Innovation und sowas wie Frontrunning hier
> bei uns dringendst vonnöten

Nur braucht Innovation nicht nur Veränderung, sondern vor allem auch 
Verbesserung. Wir werden uns darüber eher nicht einig werden, aber Du 
siehst hier ja zumindest, daß die Ansicht, Pascal sei eine Verbesserung 
im Vergleich zu C, offensichtlich kontrovers ist.

von Jobst Q. (joquis)


Lesenswert?

W.S. schrieb:
> Jobst Q. schrieb:
>> Stringhandling ist die Bearbeitung von Strings beim Lesen und Schreiben.
>> Da der String in C nichts anderes ist als ein Zeiger auf den Anfang,
>
> O ha, Strings sind was anderes als Streams. Junge, sowas passiert mir
> selbst dann nicht, wenn ich mal zu tief ins Weinglas geschaut habe...

Du willst mir also weismachen, dass die Stringbehandlung, in der ich 
über Jahrzehnte tätig war, eigentlich Streambehandlung war?

Bevor mich das in die Verzweiflung treibt, schau ich doch mal im Lexikon 
nach:

"Eine Zeichenkette oder (aus dem Englischen) ein String ist in der 
Informatik eine Folge von Zeichen (z. B. Buchstaben, Ziffern, 
Sonderzeichen und Steuerzeichen) aus einem definierten Zeichensatz. 
Zeichen können sich in einer Zeichenkette wiederholen, die Reihenfolge 
der Zeichen ist definiert. Zeichenketten sind somit Sequenzen aus 
Symbolen mit endlicher Länge." 
https://de.wikipedia.org/wiki/Zeichenkette

und

"Mit Datenströmen (englisch data streams) bezeichnet man in der 
Informatik einen kontinuierlichen Fluss von Datensätzen, dessen Ende 
meist nicht im Voraus abzusehen ist; die Datensätze werden fortlaufend 
verarbeitet, sobald jeweils ein neuer Datensatz eingetroffen ist. Die 
einzelnen Datensätze sind dabei von beliebigem, aber festem Typ. Die 
Menge der Datensätze pro Zeiteinheit (Datenrate) kann variieren und 
evtl. so groß werden, dass die begrenzten Ressourcen zur 
Weiterverarbeitung nicht ausreichen und der Empfänger entsprechend 
reagieren muss (z. B. verwerfen von Datensätzen). Im Gegensatz zu 
anderen Datenquellen können Datenströme nur Satz um Satz fortlaufend 
verarbeitet werden - insbesondere ist im Gegensatz zu Datenstrukturen 
mit wahlfreiem Zugriff (wie z. B. Arrays) meist nur ein sequentieller 
Zugriff auf die einzelnen Datensätze möglich."
https://de.wikipedia.org/wiki/Datenstrom


Also bist du wohl derjenige, der zu tief ins Weinglas geschaut hat.

von Nop (Gast)


Lesenswert?

Und nochwas zum Thema "Innovation". Die bestehende Quellcodemenge, die 
für C bereits verfügbar ist, stellt einen erheblichen geschaffenen Wert 
dar. Wollte man den wegwerfen, dann müßte eine Alternative soviel besser 
sein, daß sich das in absehbarer Zeit überhaupt lohnen würde. Ansonsten 
wäre es keine Innovation, sondern lediglich unterm Strich schädlicher 
Aktionismus, der Innovation vortäuschen soll.

Auf dem PC, mit GUI-Framneworks usw., hat man diesen Schritt gemacht, 
weil reines C dafür von vornherein ein ziemlicher Krampf war und nie so 
richtig gut funktioniert hat. Nur, da ist Pascal auch keine Alternative, 
weil es lediglich eine andere prozedurale Sprache ist, die obendrein 
auch noch fragmentiert ist wie Hulle.

Es gibt nunmal nicht nur revolutionäre Fortschritte, sondern auch 
evolutionäre. Zwischen Umbrüchen wird erstmal der Bestand verbessert und 
optimiert. Die Erwartungshaltung, man wolle nur noch Umbrüche haben, ist 
fehlgeleitet, weil man dann nur noch deren Kosten hat, ohne aber von 
ihrem Nutzen danach zu profitieren.

Und obendrein gibt es dann auch noch Rückschritte und klare 
Verschlechterungen. Wenn man heutzutage Windows, Spiele usw. ohne 
Onlineanbindung gar nicht mehr betreiben kann, ist das ein Beispiel 
dafür. Die fliegenden Autos mit Atomantrieb, von denen man in den 50ern 
als Zukunfts-Innovation geschwärmt hat, sind ja glücklicherweise nie 
auch nur ins Versuchsstadium gekommen.

Wo ich für die Zukunft Potential sehe, ist Parallelisierung. Die 
einzelnen CPU-Kerne werden kaum noch stärker, das Ende der Fahnenstange 
ist so ziemlich erreicht. Aber man kann immer mehr parallel davon haben, 
was nur derzeit kaum Sinn ergibt, außer für Spezialanwendungen. Und 
selbst da ist es schwierig.

Sowohl prozedural als auch mit OOP kommt man da nicht weiter. 
Funktionale Sprachen wären ein Weg, weil es dort keinen state gibt, den 
man gegen Parallelismus verwalten müßte. Deswegen kam Google mit 
Map-Reduce ums Eck, während Microsoft immer noch vergeblich versucht, 
überhaupt eine Suchmaschine zu etablieren.

Funktionale Sprachen wie Lisp sind erheblich langsamer als C, das ist 
Fakt. Selbst wenn Lisp compiliert wird. Allerdings könnte man es in C 
schon grundsätzlich völlig vergessen, eine Anwendung zu schreiben, die 
auf ein paar zigtausend, geschweige denn hunderttausenden Knoten 
skaliert.

Gut, Lisp hat sich aus gutem Grund nie ernsthaft durchgesetzt (((und das 
nicht wegen der Klammern))), aber ich sehe bei funktionaler 
Programmierung für große Anwendungen durchaus Potential. Jenseits von C. 
;-)

von W.S. (Gast)


Lesenswert?

Nop schrieb:
> Wollte man den wegwerfen...

Soll ich dir aufzählen, was in der Geschichte so alles weggeworfen 
worden ist? Geht nicht, es ist viel zu viel. Jedes Ding hat seine Zeit 
und mir kommt dabei Mephisto aus Faust in den Sinn: "denn alles was 
entsteht, ist wert, daß es zugrunde geht;" - allerdings teile ich 
Mephistos Meinung nicht, denn es war auch mal wert, daß es entstanden 
ist und benutzt wurde.

Ob man das nun ausgerechnet an Pascal festmachen will, ist eigentlich 
egal, es kommt nur drauf an, es eben nicht weiter so zu machen wie C. 
Egal, wie groß die Berge der zurückliegenden Quellcodes auch sein mögen.

Apropos: nicht der konkrete Quellcode ist wertvoll, sondern der Wert 
steckt in den gefundenen Algorithmen und gewonnenen Erkenntnissen. 
Typisches Beispiel ist die FFT, egal ob sie in Assembler, C oder Pascal 
formuliert ist. Der Wert von Einsteins Relativitätstheorie steckt ja 
auch nicht im Papier des Buches, wo es gedruckt ist.

Ansonsten geb ich dir durchaus Recht -mit einer Einschränkung: Wir alle 
können nur die Historie analysieren und Erkenntnisse draus ziehen und 
wir können eine Ansicht über die Gegenwart haben - aber in die Zukunft 
blicken kann keiner und sie hat schon immer für Überraschungen gesorgt.

Vielleicht sehen es künftige Generationen als unnütz an, die 
Rechentechnik immer weiter zu treiben - wer weiß?. Wir haben ja jetzt 
schon mehr als genug davon, so daß zum Verkauf neuerer Produkte 
zuvörderst erstmal der Bedarf daran erzeugt werden muß.

W.S.

von Nop (Gast)


Lesenswert?

W.S. schrieb:
> Soll ich dir aufzählen, was in der Geschichte so alles weggeworfen
> worden ist?

Aber nicht, weil man aus Langeweile einfach mal so "alles neu macht der 
Mai" spielen wollte, das ist der Punkt. Pferdekutschen hat man nach und 
nach aufgegeben, weil das Auto schließlich praktikabler war und nicht, 
weil es innovativer war. Röhrenrechner hat man aufgegeben, weil 
Transistor-basierte Rechner nicht nur schneller, sondern auch 
Dimensionen sparsamer waren.

Mit anderen Worten, Innovation ja, ABER sie muß auch einen Nutzen 
vorweisen, der das lohnenswert macht. Veränderung ist nur eine 
notwendige, aber keine hinreichende Bedingung für Fortschritt.

Und wenn Du meinst, daß nicht der konkrete Quellcode nützlich ist: es 
steht Dir frei, z.B. den kompletten Linuxkernel von C nach Pascal zu 
portieren (oder nach was-weiß-ich). Scheint ja keine Kosten zu 
verursachen, also mach doch einfach mal.

Insofern, doch, auch der konkrete Quellcode stellt geronnenen Wert dar. 
Insbesondere, wenn er nach Mannjahrhunderten nicht nur als 
Spielzeugalgorithmus besteht, sondern reifgetestet und debuggt wurde. 
Wollte man "from scratch" in einer "besseren Sprache" alles neu machen, 
wäre das nicht besser, sondern schlechter, weil dann neue Bugs drin 
wären, die auch wieder rausgetestet werden müßten. Netscape ist genau 
daran eingegangen, und das waren nicht die einzigen.

Siehe auch Joel on Software dazu: 
http://www.joelonsoftware.com/articles/fog0000000069.html

von (prx) A. K. (prx)


Lesenswert?

Nop schrieb:
> Und wenn Du meinst, daß nicht der konkrete Quellcode nützlich ist: es
> steht Dir frei, z.B. den kompletten Linuxkernel von C nach Pascal zu
> portieren (oder nach was-weiß-ich).

Du hattest zwar vorhin Lisp genannt, aber für die hiesigen Fans strenger 
Logik hätte ich einen besseren Vorschlag: "Programmation en Logique" aka 
"Programmieren in Logik" aka Prolog. ;-)
Das gab es sogar mal von Borland.

: Bearbeitet durch User
von Oliver S. (oliverso)


Lesenswert?

W.S. schrieb:
> Apropos: nicht der konkrete Quellcode ist wertvoll, sondern der Wert
> steckt in den gefundenen Algorithmen und gewonnenen Erkenntnissen.

Bis zu diesem Zitat hätte ich dir ja zumindest zugestanden, daß du doch 
auch etwas reale Erfahrung hast. Das war wohl ein Irrtum. Also doch nur 
ein reiner Theoretikus.

Bevor die aber die ganze C-Software umschreibst, fang doch erst mal mit 
all den existierenden Fortran- und Cobolprogrammen an. Denn von der 
reinen Programmiersprachenlehre ist das doch alles noch viel mehr Aua.

Oliver

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


Lesenswert?

Nop schrieb:
> Und wenn Du meinst, daß nicht der konkrete Quellcode nützlich ist: es
> steht Dir frei, z.B. den kompletten Linuxkernel von C nach Pascal zu
> portieren (oder nach was-weiß-ich).

Pascal wurde schon vor langer langer Zeit von Wirth höchstpersönlich 
durch Modula-2 abgelöst. Und wenn man mal schaut, was denn der 
Nachfolger von Modula-2 ist, gelangt man am Ende seiner Nachforschungen 
bei Oberon. Auch da hatte Niklas Wirth seine Finger mit drin.

Und siehe da: Oberon ist nicht nur eine praxisgerechte 
Programmiersprache, die nicht nur zu Lehrzwecken entwickelt wurde, 
sondern auch tauglich zur Entwicklung von Betriebssystemen:

"Das ETH Oberon System ist ein eigenständiges Betriebssystem der ETH 
Zürich, das in der Sprache Oberon implementiert ist, als 
Entwicklungsgrundlage für die Sprache diente und ebenso wie der Compiler 
kostenlos erhältlich ist."

Quelle: https://de.wikipedia.org/wiki/Oberon_(Programmiersprache%29

Also wenn, dann Oberon und nicht das angestaubte Pascal, bei welchem 
schon viel zu viele Frickler viel zu viele protprietäre Erweiterungen 
angeschflanscht haben, damit es überhaupt in der Praxis handhabbar 
wurde.

@W.S.

Statt dauernd enorme Energien darauf zu verschwenden, auf C zu schimpfen 
und es trotzdem angewidert zu verwenden, solltest Du besser etwas neues 
schaffen. Nicht lamentieren sondern Fakten schaffen! Solange man nur 
jammert, wird sich nichts ändern.

: Bearbeitet durch Moderator
von Le X. (lex_91)


Lesenswert?

Frank M. schrieb:
> Statt dauernd enorme Energien darauf zu verschwenden, auf C zu schimpfen
> und es trotzdem angewidert zu verwenden, solltest Du besser etwas neues
> schaffen. Nicht lamentieren sondern Fakten schaffen! Solange man nur
> jammert, wird sich nichts ändern.

Auch wenn ich dir ansonsten zustimmen muss halte ich diesen Absatz für 
ein Totschlagargument.

Ich kann auch etwas kritisieren ohne es selbst besser lösen zu können 
(egal wieso, sei es aus Mangel an Zeit, Geld, Infrastruktur, Wissen, 
Fähigkeiten).

Wenn eine GUI (am besten eines OSS-Tools) sich unlogisch und fummelig 
verhält kann ich das kritisieren, auch wenn ich nur dummer Anfänger bin 
und von Programmieren keine Ahnung habe.

Wenn unsre Obrigkeit keine Lösung für Atommüll erarbeiten kann sondern 
nur planlos hin- und herdiskutiert kann ich das kritisieren ohne selbst 
zu wissen was wir mit dem Zeug tun sollen, geschweigedenn eine Lösung 
initiieren oder umsetzen zu können.

Mit "machs doch besser" kann man wunderbar jede Diskussion abwürgen, und 
ist sie auch noch so sinnfrei.

: Bearbeitet durch User
von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Le X. schrieb:
> Mit "machs doch besser" kann man wunderbar jede Diskussion abwürgen, und
> ist sie auch noch so sinnfrei.

Mag sein, aber W.S.' Gejammer bringt auch bloß keinen auch nur einen
Millimeter weiter.

von Le X. (lex_91)


Lesenswert?

Jörg W. schrieb:
> Mag sein, aber W.S.' Gejammer bringt auch bloß keinen auch nur einen
> Millimeter weiter.

Er hat ja zumindest im Ansatz recht.
C hat Altlasten, C ist nicht für alles gut geeignet (GUI, Skripte zum 
Auswerten von Textdateien), C erfordert manchmal einfach ein 
akzeptieren, ein "ist halt so".

Das hat aber auch garkeiner hier bestritten.
Er zieht halt die falschen Schlüsse daraus, würde C gerne durch was 
inkompatibles Neues ersetzen. In 5 Jahren kommt dann der nächste, findet 
Kleinigkeiten und fordert wiederum eine neue Sprache.

Drausen wo gearbeitet wird, wo Werte geschaffen werden gehts halt 
dreckig zu.
Da muss man halt mal mit einer Lösung leben und gut ist.
Wir sind hier nicht im Elfenbeinturm.

Ich kenne auch Entwickler die ständig die 110%-Lösung wollen, die aber 
nie fertig wird und für den Kunden unbenutzbar ist.

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

Le X. schrieb:
> Ich kann auch etwas kritisieren ohne es selbst besser lösen zu können

Wenn Du aber etwas besseres willst und es selbst nicht kannst, dann 
musst Du halt jemanden dafür bezahlen, der es für Dich macht. Wenn man 
das auch nicht kann, dann ist es der denkbar schlechteste Weg, etwas 
besseres zu fordern aber keinen Finger dafür krumm machen zu wollen.

Mit welchem Recht kann man etwas von anderen fordern, ohne sich selbst 
mit einzubringen - egal ob selbst oder zumindest monetär?

Le X. schrieb:
> Mit "machs doch besser" kann man wunderbar jede Diskussion abwürgen, [...]

Unsinn. Man kann es besser machen, wenn man es tatsächlich braucht. 
Immer. Und Du kannst Dich auch nicht damit herausreden, dass W.S. zu 
dumm dafür sei. Ist er nämlich nicht. Aber das Gejammer geht mir 
ziemlich auf den Nerv.

Stell Dir mal vor, wir lägen alle irgendwo wimmernd in der Ecke. Dann 
ginge nix mehr.

von (prx) A. K. (prx)


Lesenswert?

Le X. schrieb:
> Ich kenne auch Entwickler die ständig die 110%-Lösung wollen, die aber
> nie fertig wird und für den Kunden unbenutzbar ist.

Eine Firma, die Software erst raus bringt, wenn der Entwickler sie als 
fertig ansieht, die macht Pleite. Deshalb gibt es z.B. lange vorher 
festgelegte Release-Zeitpunkte. Und da kommt raus, was man hat, nicht 
was man gerne hätte.

von Le X. (lex_91)


Lesenswert?

Frank M. schrieb:
> Man kann es besser machen, wenn man es tatsächlich braucht.

"Wenn man es braucht" ist wohl der knackpunkt.
Kommt immer auf den Leidensdruck an.
Wenn ich zuhause ein Tool benutze das sich unlogisch verhält schüttel 
ich den Kopf oder fluche kurz, arrangiere mich aber damit.
Wenn in der Arbeit sowas nicht tut muss ich die Arschbacken 
zusammenkneifen und das Problem fixen, weil die Lösung am Schluß 
zuverlässig laufen muss.

Bei W.S. ist wohl der Leidensdruck mittelmäsig.
Er ist genervt genug zum Dauermeckern, hat aber nicht den Druck 
irgendwas ändern zu MÜSSEN.
Das ist dann eine blöde Situation. ;-)

Frank M. schrieb:
> Unsinn.
Ein Argument welches mit "Unsinn" beginnt sollte man eigentlich 
ignorieren wenn man nicht will dass der Thread ins Chaos abdriftet 
(siehe A&B Forum).
Ich mach hier mal ne Ausnahme ;-)

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

Le X. schrieb:
> Er zieht halt die falschen Schlüsse daraus, würde C gerne durch was
> inkompatibles Neues ersetzen.

Warum tut er das dann nicht? Selbst wenn er es nicht persönlich kann, 
kann man doch wenigstens die verbersserten Ansätze der Sprache D (als 
Nachfolger von C) beschreiben und dokumentieren. Wenn man dafür Leute 
begeistern kann, wird man auch ein Team schaffen, die diese Ideen auch 
umsetzen.

Ich persönlich war 2000 auch davon genervt, dass immer nur einer in der 
Familie über DSL surfen konnte, weil damals das dumme DSL-Modem ohne 
Router-Eigentschaften direkt in den PC gesteckt werden musste. Aber 
statt mich darüber aufzuregen und öffentlich rumzujammern, habe ich 
damals eine Router-Lösung geschaffen, die auf einem ausgedienten PC mit 
einer einzelnen 1,44MB-Diskette lief. Daraus wurde dann fli4l, der erste 
massentaugliche Homerouter mit einigen hunderttausend Anwendern.

Auch der längste Weg beginnt mit dem ersten Schritt.
(Konfuzius)

von Le X. (lex_91)


Lesenswert?

A. K. schrieb:
> Eine Firma, die Software erst raus bringt, wenn der Entwickler sie als
> fertig ansieht, die macht Pleite. Deshalb gibt es z.B. lange vorher
> festgelegte Release-Zeitpunkte. Und da kommt raus, was man hat, nicht
> was man gerne hätte.

Eben.
Oder anders ausgedrückt:
man muss sich mit dem arrangieren was man hat, z.B. mit der 
Programmiersprache C.
Die Dauersuche nach der akademischen Musterlösung ist nicht 
wirtschaftlich.

von (prx) A. K. (prx)


Lesenswert?

Frank M. schrieb:
> Warum tut er das dann nicht? Selbst wenn er es nicht persönlich kann,
> kann man doch wenigstens die verbersserten Ansätze der Sprache D (als
> Nachfolger von C) beschreiben und dokumentieren.

Eine Sprache, die auf eine einzige Person zurück geht: Walter Bright, 
dem PCs auch den ersten nativen C++ Compiler verdanken.

Er hatte Ideen und realisierte sie, dabei Kompatibilität zu C über Bord 
werfend. Weshalb das auch D heisst, und nicht C(Version20xx).

> Daraus wurde dann fli4l, der erste
> massentaugliche Homerouter mit einigen hunderttausend Anwendern.

Dafür nachträglich ein dickes Dankeschön.

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


Lesenswert?

A. K. schrieb:
> Weshalb das auch D heisst, und nicht C(Version20xx).

Mift. Also ist der Name D schon belegt. Mit unserer eigens neu zu 
schaffenden Programmiersprache müssen wir uns also zwischen C und D 
quetschen. C++ ist ebenso schon belegt, bleibt also noch D-- übrig :-)

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


Lesenswert?

Frank M. schrieb:
> Auch der längste Weg beginnt mit dem ersten Schritt.

Da wir gerade von unsinnigem Hin-und-Her-Argumentationen zu
Anekdoten übergehen. ;-)

Ging mir damals ähnlich, aber noch vor DSL, mit ISDN.  Hellmuth
Michaelis hatte zwar für *BSD eine schöne ISDN-Suite, aber er hatte
keinen Leidensdruck, darüber PPP fahren zu müssen, daher stand das
nicht auf seiner Agenda.  Ich habe mir dann eine angefrühstückte
SyncPPP-Implementierung, die schon im FreeBSD vorhanden war, aber die
nicht für Wählverbindungen konzipiert waren (kennt jemand heute noch
Standleitungen mit Bitstrom-Protokollen? ;-) genommen, mir die
PPP-RFCs dazu geschnappt, und implementiert, was man implementieren
musste (dabei die Qualität dieser RFCs schätzen gelernt).

Zurück zu obiger Argumentation: ich hätte mich stattdessen auch
hinstellen können, und Hellmuth damit nerven, dass das von ihm
lediglich vorgesehene simple Cisco-lastige raw protocol doch sowas
von K*cke ist, dass man da was moderneres braucht, dass ich damit
nicht leben kann, etc. pp.  Vermutlich hätte ich aber auch ein Jahr
später noch keine benutzbare Lösung gehabt. :-)

(Mir ist so, als würde NetBSD „meine“ Implementierung nach wie vor
für PPP-over-Ethernet benutzen.  Kann mich aber irren, habe da lange
nicht mehr reingesehen.)

von (prx) A. K. (prx)


Lesenswert?

Jörg W. schrieb:
> kennt jemand heute noch Standleitungen mit Bitstrom-Protokollen? ;-)

SDLC/HDLC? Das bildet die Basis des D-Kanal-Protokolls von ISDN.

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


Lesenswert?

A. K. schrieb:
> Jörg W. schrieb:
>> kennt jemand heute noch Standleitungen mit Bitstrom-Protokollen? ;-)
>
> SDLC/HDLC? Das bildet die Basis des D-Kanal-Protokolls von ISDN.

Das ist mir schon klar, aber wer hat denn heutzutage noch eine
Mietleitung, die von A nach B führt und so ein Protokoll fährt?

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

Jörg W. schrieb:
> Das ist mir schon klar, aber wer hat denn heutzutage noch eine
> Mietleitung, die von A nach B führt und so ein Protokoll fährt?

Diverse Unternehmen/Behörden, die Upstreams zu Satelliten angemietet 
haben. Okay, die "Mietleitung" besteht nicht aus Kupfer, aber es ist 
schon eine Leitung von A nach B. Ich habe da in den 90er Jahren 
Unix-Rechner über SDLC/HDLC über Uplinkschüsseln mit mehreren Metern 
Durchmesser an Satelliten angebunden. War ein sehr interessantes Projekt 
- auch wenn dann am anderen Ende kein Unix-Rechner, sondern ein IBM-Host 
stand.

: Bearbeitet durch Moderator
von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Frank M. schrieb:
> Diverse Unternehmen/Behörden, die Upstreams zu Satelliten angemietet
> haben.

Ah OK.  Den Anwendungsfall kannte ich so nicht.

Aber als reine Internet-Links (wie vor 20+ Jahren) dürften sie
mittlerweile weitgehend verschwunden sein.

von Rolf Magnus (Gast)


Lesenswert?

Frank M. schrieb:
> A. K. schrieb:
>> Weshalb das auch D heisst, und nicht C(Version20xx).
>
> Mift. Also ist der Name D schon belegt. Mit unserer eigens neu zu
> schaffenden Programmiersprache müssen wir uns also zwischen C und D
> quetschen. C++ ist ebenso schon belegt, bleibt also noch D-- übrig :-)

Oder D♭ (des - auf Englisch "d flat"), analog zu C♯ (cis - auf Englisch 
C sharp).
https://en.wikipedia.org/wiki/D%E2%99%AD_(musical_note)

Nop schrieb:
> Wir werden uns darüber eher nicht einig werden, aber Du siehst hier ja
> zumindest, daß die Ansicht, Pascal sei eine Verbesserung im Vergleich zu
> C, offensichtlich kontrovers ist.

Ich vermute, dass er das bisher überhaupt nicht gesehen hat, da er seine 
eigene Meinung einfach zur unumstößlichen Tatsache und alle, die was 
anderes sagen, zu Idioten erklärt. Im übrigen ein Diskutierstil, der 
alles andere tut als den Fortschritt zu fördern.

von (prx) A. K. (prx)


Lesenswert?

Da wird grad bei D waren: Ich hatte mir das vor längerer Zeit mal 
angesehen, aber es hat sich seither weiter entwickelt. Es lohnt sich, da 
mal rein zu sehen:
http://dlang.org/spec/spec.html
https://en.wikipedia.org/wiki/D_(programming_language)

Um ein paar Dinge zu nennen:

So halte ich die Contracts für eine recht nette Idee. Klar, man kann 
(und sollte) das, was im Contract steht, sowieso in die Funktion packen. 
Aber man vergisst man das gerne und so ist es übersichtlicher.

Dann gibt es einen Subset SafeD, in dem der Compiler sicherstellt, dass 
dieser Code keine unsicheren Speicherzugriffe durchführen kann.

Die Deklarations-Syntax ist linear, nicht mehr anhand von Prioritäten 
verschachtelt. "int*[] a,b" statt "int *a[],*b[]" beispielsweise.

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


Lesenswert?

A. K. schrieb:
> Es lohnt sich, da mal rein zu sehen:
> http://dlang.org/spec/spec.html
> https://en.wikipedia.org/wiki/D_(programming_language)

Ich lese da auch schon seit einer guten Stunde drin rum, sehr 
interessant :-)

> So halte ich die Contracts für eine recht nette Idee.

Ja, sehr interessant - auch wenn man das klassisch ebenso formulieren 
könnte. Nur bei den Invariants habe ich noch Verständnisprobleme. Wann 
werden die Prüfungen durchgeführt? Ausschließlich im Constructor?

> Dann gibt es einen Subset SafeD, in dem der Compiler sicherstellt, dass
> dieser Code keine unsicheren Speicherzugriffe durchführen kann.

Was mich direkt zu den Arrays und den neuartigen Operatoren auf Arrays 
geführt hat, z.B. das Kopieren mittels:
1
s[1..2] = t[0..1];

Wenn man so überlappende Speicherbereiche kopiert, gibts einen Fehler. 
Sehr nett. :-)

Was ist mit Strings? Da ist zu lesen:

   "A string is an array of characters.".

Also doch alles wie in C, was Strings betrifft?

Weiter:

    "Since strings, however, are not 0 terminated in D, when
    transferring a pointer to a string to C, add a terminating 0"

Wohl nicht, das terminierende NUL gibt es nicht in D...

Zuletzt: "printf() is a C function and is not part of D."

Upps, kein printf() in D. Um es zu verwenden, muss der D-String mittels 
Terminierung in einen C-String umgewandelt werden:
1
  str ~= "\0";
2
  printf("the string is '%s'\n", cast(char*)str);

Finde ich nicht so gelungen.

> Die Deklarations-Syntax ist linear, nicht mehr anhand von Prioritäten
> verschachtelt. "int*[] a,b" statt "int *a[],*b[]" beispielsweise.

Multiple Definitionen von mehreren Variablen in einem Statement würde 
ich abschaffen. Finde ich überflüssig und unleserlich, egal ob jetzt in 
C oder in D.

: Bearbeitet durch Moderator
von Franz Ferkel (Gast)


Lesenswert?

Darf man fragen ob dieser Thread auch eine for(;;) ist ?

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

Franz Ferkel schrieb:
> Darf man fragen ob dieser Thread auch eine for(;;) ist ?

Och komm, eine Diskussion über for(;;) selbst ist doch totlangweilig... 
:-)

Außerdem ist heute Freitag.

Hab noch was gefunden:

"The best way is to use std.stdio.writefln, which can handle D strings:"

  import std.stdio;
  writefln("the string is '%s'", str);

Man braucht also gar kein C-printf() und damit auch keine Terminierung 
in D.

Ontopic: Eine Endlosschleife in D muss man wohl genau wie in C 
formulieren. Oh, watt is datt schlimm...

von Kaj (Gast)


Lesenswert?

Jörg W. schrieb:
> Mir ist so, als würde NetBSD „meine“ Implementierung nach wie vor
> für PPP-over-Ethernet benutzen.
Ist doch schoen, wenn es so ist, oder etwa nicht? :)

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


Lesenswert?

Kaj schrieb:
> Ist doch schoen, wenn es so ist, oder etwa nicht?

Yep, zumal das eine Anwendung ist, an die ich beim Erstellen der
Software nicht einmal hätte denken können. ;)

von Jobst Q. (joquis)


Lesenswert?

Frank M. schrieb:
> Was ist mit Strings? Da ist zu lesen:
>
>    "A string is an array of characters.".
>
> Also doch alles wie in C, was Strings betrifft?
>
> Weiter:
>
>     "Since strings, however, are not 0 terminated in D, when
>     transferring a pointer to a string to C, add a terminating 0"
>
> Wohl nicht, das terminierende NUL gibt es nicht in D...

Und wo ist da der Fortschritt von D gegenüber C?

Speicherblöcke, die '\0' enthalten können, kann man in C auch mit den 
mem... Funktionen behandeln. Innerhalb eines Strings hat ein Nullbyte 
keine sinnvolle Verwendung.

In C kann man wegen der Nullterminierung einen String sehr einfach und 
effizient ohne Rumkopieren in mehrere Teilstrings aufteilen, indem man 
Trennzeichen durch '\0' ersetzt. In D ginge das nicht mehr. Toller 
Fortschritt!

von (prx) A. K. (prx)


Lesenswert?

Jobst Q. schrieb:
> Speicherblöcke, die '\0' enthalten können, kann man in C auch mit den
> mem... Funktionen behandeln.

Es geht in D nicht darum, ob man damit etwas kann, was man in C nicht 
kann. Dem ist nicht so. Es geht um das wie, nicht um das ob.

C ist Turing-vollständig. Du solltest also auf die Turing-Maschine 
umsteigen. Die kann alles was Assembler kann, alles was C kann, alles 
was C++ kann, alles was Java kann, alles was ... Und ist zudem viel 
leichter verständlich. ;-)

von Nop (Gast)


Lesenswert?

Ok ok, aber die entscheidende Frage ist doch: Kann man denn auch in D 
wirklich Fortran programmieren? duck

von (prx) A. K. (prx)


Lesenswert?

Nop schrieb:
> Ok ok, aber die entscheidende Frage ist doch: Kann man denn auch in D
> wirklich Fortran programmieren? *duck*

Aber klar doch. Du kannst dir darin beispielsweise einen FORTRAN 
Compiler schreiben. Ist sogar leichter als umgekehrt. ;-)

von Nop (Gast)


Lesenswert?

A. K. schrieb:
> Du kannst dir darin beispielsweise einen FORTRAN
> Compiler schreiben.

Das kann man auch in Pascal, insofern wäre das Cheaten. ;-)

von (prx) A. K. (prx)


Lesenswert?

Ist eine Sprache besser, wenn man sich mit ihr leichter ins Knie 
schiessen kann? Oder führt das am Ende bloss zu lauter Gehbehinderten?

Es mag zwar vielen Schreinern gelingen, ein Bandsäge zu benutzen, ohne 
am Ende wie Monty Pythons Schwarzer Ritter auszusehen. Programmierern 
gelingt das jedoch nicht. Sie haben nur das Glück, dass es eher die 
anderen Leute sind, die dabei verlieren. Vielleicht wärs also besser, 
deren Alltagswerkzeuge etwas weniger gefährlich zu machen.

: Bearbeitet durch User
von Jobst Q. (joquis)


Lesenswert?

A. K. schrieb:
> Es geht in D nicht darum, ob man damit etwas kann, was man in C nicht
> kann. Dem ist nicht so. Es geht um das wie, nicht um das ob.

Umständlicher gehts immer. Das ist aber noch kein Fortschritt.

C ist ein Riesenfortschritt gegenüber Assembler, weil es von der 
Hardware abstrahiert und mit guten Compilern fast die gleiche Effizienz 
erreichen kann. C++ ist ein Fortschritt gegenüber C, weil es 
objektorientiertes Programmieren ermöglicht, aber es eben nicht 
erzwingt, sondern einfaches C mit umfasst.

D scheint da mehr ein C-- zu sein, da es die Möglichkeiten von C 
beschneidet und effiziente Funktionen durch umständlichere Methoden 
ersetzt.

von (prx) A. K. (prx)


Lesenswert?

Jobst Q. schrieb:
> D scheint da mehr ein C-- zu sein, da es die Möglichkeiten von C
> beschneidet und effiziente Funktionen durch umständlichere Methoden
> ersetzt.

Völlig richtig. Es wird deutlich umständlicher, sich ins Knie zu 
schiessen. Es mag dir seltsam vorkommen, aber ich sehe darin einen 
Fortschritt.

: Bearbeitet durch User
von Smarti (Gast)


Lesenswert?

Ich finde die entsprechende AN nicht aber von Atmel gibt es Tipps für 
Speicheroptimierung / Geschwindigkeit z.B.

Atmel AVR4027: Tips and Tricks to Optimize
Your C Code for 8-bit AVR Microcontrollers

Im Endeffekt was der Compiler aus dem C Code macht.

Sprich for (;;) wird vom Compiler "am Besten" umgesetzt.

von Nop (Gast)


Lesenswert?

Eine anfängertaugliche Programmiersprache gibt's doch schon seit 1964. 
Man muß keinen portablen Makroassembler nehmen, wenn man keine 
Performance haben will.

von Jobst Q. (joquis)


Lesenswert?

A. K. schrieb:
> Völlig richtig. Es wird deutlich umständlicher, sich ins Knie zu
> schiessen. Es mag dir seltsam vorkommen, aber ich sehe darin einen
> Fortschritt.

Mit einem Messer kann man sich erstechen, mit einem Gürtel kann man sich 
aufhängen. Aber warum sollte man das tun? Trotzdem möchte ich weder auf 
messer noch auf Gürtel verzichten. Und in so einer Pädagogenwelt, in der 
alles verboten ist, womit man sich schaden könnte, möchte ich nicht 
leben.

von (prx) A. K. (prx)


Lesenswert?

Jobst Q. schrieb:
> Mit einem Messer kann man sich erstechen, mit einem Gürtel kann man sich
> aufhängen.

Das ist wahr. Aber warum tun Programmierer das andauernd? Also warum 
erstechen Programmierer immer mal andere Leute oder erhängen sie? Denn 
das tun sie immer und immer wieder. Würden sie nicht andere Leute damit 
plagen, sondern sich selber, wärs schnell aus mit Gürtel und Messer. 
Oder mit dem Programmierer.

: Bearbeitet durch User
von Nop (Gast)


Lesenswert?

A. K. schrieb:
> Aber warum tun Programmierer das andauernd?

Tun sie nicht. Da, wo es geht, verwendet man heute kein C mehr. Und 
tunlichst auch kein C++. Server-Anwendungen im größeren Maßstab macht 
man nicht mehr in Lowlevelsprachen.

Aber Mikrocontroller sind kostensensitiv. Eine Bloatsprache mit allen 
Sicherheitsnetzen erzwingt nunmal einen größeren und damit teureren 
Controller. Bei entsprechenden Stückzahlen ist man damit aus dem Rennen 
gegenüber der Konkurrenz. Da kann man es sich nunmal nicht leisten, den 
halben Controller schon mit Müsli zu füllen.

von (prx) A. K. (prx)


Lesenswert?

Nop schrieb:
> Server-Anwendungen im größeren Maßstab macht
> man nicht mehr in Lowlevelsprachen.

Stimmt. Das macht man beispielsweise in PHP. ;-)

von (prx) A. K. (prx)


Lesenswert?

Nop schrieb:
> Da kann man es sich nunmal nicht leisten, den
> halben Controller schon mit Müsli zu füllen.

Stimmt. Man bewirft mit dem Mirai-Müsli statt dessen den Rest der Welt.

von Nop (Gast)


Lesenswert?

A. K. schrieb:
> Man bewirft mit dem Mirai-Müsli statt dessen den Rest der Welt.

Mag sein, aber wenn man es nicht tut, ist man pleite, und zwar deutlich 
bevor die Konkurrenz wegen Sicherheitslücken ein Update bringen muß.

Das ist ja auch der Grund für MISRA - daß man im Regelfall C auf sehr 
pascalhafte Weise programmiert. Nur, wenn es technisch begründbar 
angemessen ist, dann darf man auch davon abweichen. Man muß nur 
analysieren, daß das dann kein Problem ergibt.

von (prx) A. K. (prx)


Lesenswert?

Nop schrieb:
> Mag sein, aber wenn man es nicht tut, ist man pleite, und zwar deutlich
> bevor die Konkurrenz wegen Sicherheitslücken ein Update bringen muß.

Yep. Jetzt kommen wir langsam zum Punkt. Also weshalb beispielsweise 
manche Routerhersteller nicht schon längst pleite sind, obwohl sie 
zusammengeschluderte Firmware lange bekannten Exploits bringen und nie 
fixen, dafür aber vorsätzlich gleich mehrere Backdoors einbauen.

Tja, die Welt ist unfair. Hätte AVM nicht vorbildlich gehandelt - die 
wären jetzt wohl pleite. Die Konkurrenz aus Billigstan und 
Nochbilligerstan macht seelenruhig weiter und niemanden scheint es zu 
stören.

: Bearbeitet durch User
von Nop (Gast)


Lesenswert?

A. K. schrieb:
> Hätte AVM nicht vorbildlich gehandelt - die
> wären jetzt wohl pleite.

Soso. Die haben also ein Linux, was nicht in C programmiert ist. 
Interessant.

(Es ging hier nicht um die Frage, ob man Updates bringt, wenn Lücken da 
sind, sondern darum, daß man nicht in C programmieren sollte, damit 
weniger Lücken entstehen!)

von (prx) A. K. (prx)


Lesenswert?

Nop schrieb:
> Soso. Die haben also ein Linux, was nicht in C programmiert ist.
> Interessant.

Quark.

> (Es ging hier nicht um die Frage, ob man Updates bringt, wenn Lücken da
> sind, sondern darum, daß man nicht in C programmieren sollte, damit
> weniger Lücken entstehen!)

Meine Aussage war eine Reaktion auf die von dir genannten zutreffenden 
wirtschaftlichen Zwänge. Mit C hatte sie nichts zu tun. Das Problem 
liegt aber ähnlich.

Es ist oftmals erlaubt, billigst zu bauen und die Scheisse zum Himmel 
stinken zu lassen. Sorgfalt kostet, egal ob per Sprache, Hardware, Zeit 
fürs Programmieren etc. Das hast du selbst geschrieben, nur nicht so 
verallgemeinert.

Dort wo es nicht erlaubt ist, ist zumindest die Reaktion mitunter fixer.

: Bearbeitet durch User
von Klaus (Gast)


Lesenswert?

Nop schrieb:
> Aber Mikrocontroller sind kostensensitiv. Eine Bloatsprache mit allen
> Sicherheitsnetzen erzwingt nunmal einen größeren und damit teureren
> Controller. Bei entsprechenden Stückzahlen ist man damit aus dem Rennen
> gegenüber der Konkurrenz. Da kann man es sich nunmal nicht leisten, den
> halben Controller schon mit Müsli zu füllen.

Das ist Quatsch. Bei einem Chinamodul, daß portofrei fast nackt für < 2€ 
verkauft wird, mag das stimmen. Ansonsten kostet alleine das Schreiben 
des hier erforderlichen "Beipackzettels" in allen EU-Sprachen und alle 
anderen Posten wie Zulassung, Garantieabwicklung, Marketing ... bei 
einem Produkt viel, viel mehr, als die paar zusätzlichen Cent für einen 
größeren µC.

Nur der Einkauf, die Entwicklung rechnen sich da schön, für die Bilanz 
hat das keine Bedeutung.

MfG Klaus

von Nop (Gast)


Lesenswert?

A. K. schrieb:

> Quark.

War mir natürlich auch klar. ;-)

> Mit C hatte sie nichts zu tun

Eben.

> das Problem liegt aber ähnlich.

Stimmt.

> Es ist oftmals erlaubt, billigst zu bauen und die Scheisse zum Himmel
> stinken zu lassen.

Klar. Consumer kaufen alles. Hauptsache, der Schrott wird entweder mit 
entsprechendem Image beworben oder ist billig.

Aber, Fakt ist - wenn man ernsthaft Performance will, geht an C oder 
auch C++ wenig vorbei. Nehmen wir mal Schach-Engines. Die stärkste, die 
nicht in C/C++ geschrieben ist, liegt im Moment auf Platz 25 (Delphi). 
Mit einem Abstand von über 300 ELO auf die Spitze. Das ist anderthalb 
Klassen darunter.

von (prx) A. K. (prx)


Lesenswert?

Oftmals sind die Folgekosten von Produkten externalisiert. Der 
Hersteller verdient damit Geld, ist aber nicht für die Folgen 
verantwortlich. Die bleiben beim Kunden hängen.

Zwar kann niemand von Herstellern verlangen, perfekte Software zu bauen. 
Aber man sollte vielleicht verlangen können, kritische Probleme für 
einen Mindestzeitraum als vorgesehene Lebensdauer zeitnah zu fixen. Da 
diese Kosten eingepreist werden müssen, wird das Zeug natürlich teurer 
und so mancher IoT Hype verschwindet schneller wieder als er kommt.

Nur so kann eine Kultur entstehen, die Sorgfalt in der Herstellung 
lohnenswert macht. Ob das nun Werkzeuge oder Zeit betrifft. Und dann 
kann es für einen Hersteller auch lohnend sein, etwas Ressourcen für 
dein "bloat" einzurechnen.

von (prx) A. K. (prx)


Lesenswert?

Nop schrieb:
> Nehmen wir mal Schach-Engines.

Kein Problem damit. Die Folgen von Bugs sind da höchstens peinlich.

Aber wieviel Software des alltäglichen Lebens ist an der Grenze der gut 
verfügbaren Performance? Also wirklich, nicht bloss weil 25ct gespart 
für 64K statt 128K Flash. Und wieviel davon steckt an Stellen, an denen 
nicht bloss Elo-Punkte abgezogen werden, sondern ernsthaftere 
Konsequenzen drohen.

Und das betrifft nicht nur Banken und Gesundheit. Wenn 25% aller 
Kühlschränke gleichzeitig ausfallen, weil Bug oder Exploit im IoT-Modul, 
dann stinkt das ziemlich zum Himmel. Auch wörtlich.

Wie lange können wir angesichts der Durchdringung mit Software, 
besondern vernetzter Software, die bisherige Qualitätsunkultur 
durchhalten?

: Bearbeitet durch User
von Christopher C. (trihexagon)


Lesenswert?

Jobst Q. schrieb:
> A. K. schrieb:
>> Völlig richtig. Es wird deutlich umständlicher, sich ins Knie zu
>> schiessen. Es mag dir seltsam vorkommen, aber ich sehe darin einen
>> Fortschritt.
>
> Mit einem Messer kann man sich erstechen, mit einem Gürtel kann man sich
> aufhängen. Aber warum sollte man das tun? Trotzdem möchte ich weder auf
> messer noch auf Gürtel verzichten. Und in so einer Pädagogenwelt, in der
> alles verboten ist, womit man sich schaden könnte, möchte ich nicht
> leben.

Mit Schusswaffen kann man sich/jemand aus Versehen erschießen, deshalb 
gibts Sicherungen, um das zu verhindern. Und so gibt es Sprachen, die 
nach einem ähnlichen Prinzip funktionieren. Ein guter Mittelweg, wie ich 
finde.

Zeigerfrimeleien mach ich eher im Treibercode, dass ich mich damit auch 
im Code der Steuerungslogik ins Knie schießen kann, ist unnötig.

von Christopher C. (trihexagon)


Lesenswert?

Nop schrieb:
> Aber, Fakt ist - wenn man ernsthaft Performance will, geht an C oder
> auch C++ wenig vorbei. Nehmen wir mal Schach-Engines. Die stärkste, die
> nicht in C/C++ geschrieben ist, liegt im Moment auf Platz 25 (Delphi).
> Mit einem Abstand von über 300 ELO auf die Spitze. Das ist anderthalb
> Klassen darunter.

Ich bezweifle, dass das hauptsächlich an C/C++ liegt.

1. So hervorragende Kompiler (gcc, icc...), wie im C/C++ Umfeld, sind 
anderswo eher selten (wenn man mal bei den nativen Sprachen bleibt). Bei 
so viel Arbeit die da jeden Tag reingesteckt wird, ist es kein Wunder. 
Nutzt halt auch jeder, vor allem die Industrie. Das wirkt sich vor allem 
auf die Optimierung aus.

2. Wie viel Aufwand wurde denn in die Delphi-Variante im Vergleich zu 
den anderen Varianten reingesteckt? Wäre die Delphi-Variante genauso gut 
oder sogar besser als die C++-Variante auf Platz 1., wenn gleich viel 
Aufwand hineingesteckt werden würde?

3. Qualität Algorithmus? (Analog zu Punkt 2.)

Natürlich ist die Performance von C und C++ hervorragend, andere 
Sprachen könnten es aber genauso sein, wenn sie die gleiche 
Aufmerksamkeit bekommen würden.

von Roland F. (rhf)


Lesenswert?

> ...andere Sprachen könnten es aber genauso sein, wenn
> sie die gleiche Aufmerksamkeit bekommen würden.

Und warum bekommen sie die nicht? Warum floppen praktisch alle erdachten 
Sprachen, die die (vermeintlichen?) Schwächen von C und Konsorten 
abstellen wollen?

rhf

von (prx) A. K. (prx)


Lesenswert?

Roland F. schrieb:
> Warum floppen praktisch alle erdachten
> Sprachen, die die (vermeintlichen?) Schwächen von C und Konsorten
> abstellen wollen?

Mit der Qualität der Sprachen hat das nichts zu tun.

von Roland F. (rhf)


Lesenswert?

A. K. schrieb:
> Mit der Qualität der Sprachen hat das nichts zu tun.

Aber womit dann?

rhf

von Jobst Q. (joquis)


Lesenswert?

A. K. schrieb:
> Aber warum tun Programmierer das andauernd? Also warum
> erstechen Programmierer immer mal andere Leute oder erhängen sie? Denn
> das tun sie immer und immer wieder.

Echt? Ist das so? Der Mörder ist immer der Programmierer?

Na ein Glück, dass ich nur wenige Programmierer persönlich kenne. Obwohl 
ich auch Programmierer bin, verspür ich überhaupt kein Bedürfnis, 
jemanden zu erstechen oder aufzuhängen.

von Kaj (Gast)


Lesenswert?

Roland F. schrieb:
> Und warum bekommen sie die nicht? Warum floppen praktisch alle erdachten
> Sprachen, die die (vermeintlichen?) Schwächen von C und Konsorten
> abstellen wollen?
Ich denke Rust ist ein echter Kandidat, gibt es jetzt auch schon fuer 
AVR, bzw. man arbeitet dran.
https://github.com/avr-rust/rust

Warum sich gewisse Sprachen nicht durchsetzen ist einfach: Faulheit.
Die Faulheit des Menschen, sein gewohntes aufzugeben, etwas neues zu 
lernen, anders zu denken...

Schau dir doch nur mal die Disskusionen zu Python an, wie viele Leute 
sich an dem Syntaxtischen Whitespace stoeren.

Oder Rust:
Warum muss ich bei einer Variablen extra angeben, dass ich sie 
veraendern koennne moechte? (Also das gegenteil von const in C/C++)
Ist meiner Meinung nach voelliger Bloedsinn, da man in der Regel wohl > 
97% aller Variablen veraendern koennen moechte.

Und so faengt es an, mit den Vorurteilen und der Ablehnung. Obwohl ich 
die Sprache bisher nie benutzt habe, habe ich jetzt schon das Vorurteil, 
dass die Sprache mist ist, mag sie auch noch so gute Konzepte enthalten.

Und so duerfte es jeder neuen Sprache gehen.

Dazu kommt, dass fast monatlich eine neue Sprache geboren wird, die 
verspricht, das non plus ultra zu sein, und alles besser zu machen.

Wie soll ich mich aber mit einer Sprache hinreichend auseinander setzen, 
wenn es ja fast taeglich eine neue gibt? Bis ich mich mit einer Sprache 
ausreichend beschaeftigt habe, ist sie ja schon wieder veraltet, und die 
Disskusion geht von vorne los:
Warum nutzt du denn so einen alten, unsicheren Quark?
<Hier neue Sprache einfuegen> ist viel sicherer und besser weil: ...

Ich wuerde mir echt gerne Rust naeher anschauen, aber bei genauerer 
betrachtung, bringt es mir keinen grossen Mehrwert. Warum?
Rust ist wie C -> Alles muss man selber von Hand machen.
Wenn ich mir Python und C anschaue, dann hat Python einen echten 
Mehrwert, weil es eine unglaubliche maechtige Standard Lib gibt. Nahezu 
alles was man braucht bringt Python von Hause aus mit.
Deswegen beschaeftige ich mit C und Python, weil mir jede Sprache, der 
anderen gegenueber einen echten Mehrwert hat (Geschwindigkeit <==> 
Komfort). Rust und C sind fuer mich so, als wenn ich mir 2 Fahrraeder in 
den Keller Stelle: Ja, das eine ist neuer und bietet mir etwas mehr 
Sicherheit, aber der echte Mehrwert ist mMn relativ klein.

Ausserdem ist C als Sprache stabil, da tut sich nicht mehr viel.
Wenn ich mir z.B. Python anschaue, wo von Version 3.4 auf 3.5 Methoden 
umbenannt wurden (subprocess.call <==> subprocess.run), dann ist das 
doch irgendwie Mist. (Das Abschneiden von Zoepfen und aufraeumen der 
Std-Lib wie beim Sprung von 2 auf 3 finde ich ok!) Sprachen, die sich 
noch "aktiv in der Entstehung" sind, sind halt auch unbequem und machen 
Arbeit, weil der Code mit der naechsten oder uebernaechsten Version 
vielleicht nicht mehr laeuft.
Auch das ist ein Punkt, wo ich sage: Da nutze ich lieber C, anstatt 
Rust, Julia, Go, oder wie sie nicht alle heissen.
Python hat einen Release-Zyklus von (ich glaube) 18 Monaten. Das heisst, 
du musst im schlechtesten Falle, alle 18 Monate deinen Code 
ueberarbeiten, und dafuer Sorgen, dass er mit der Aktuellen Version und 
vielleicht noch mit den letzten beiden Versionen laeuft. (Uebertriebene 
Darstellung!)

Oder noch schlimmer:
Waehrend du an einem Projekt arbeitest aendert sich die Sprache so 
stark, dass man grosse Teile des Projektes wegwerfen und komplett neu 
machen muss.

Da stellt sich natuerlich auch die Frage, ob man sich sowas Leisten kann 
und ob man sich sowas Leisten will.

Darueberhinaus gibt es natuerlich das Problem des Wissens.
Wie viele C-Programmierer findet man?
Und wieviele Programmierer findet man zu Rust oder Julia?

In C sind praktisch alle Fallstricke bekannt (Overflows, Pointer, etc.), 
sie werden nur nicht beachtet, weshalb sie immer und immer wieder 
auftauchen.

Wie ist es um das Wissen und die Dokumentation der Fallstricke in Rust 
bestellt?

Das alles sind Gruende, weshalb es neue Sprachen so schwer haben, und 
weshalb sich alte Sprachen wie C so lange halten.

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


Lesenswert?

Kaj schrieb:
> Schau dir doch nur mal die Disskusionen zu Python an, wie viele Leute
> sich an dem Syntaxtischen Whitespace stoeren.

Der Unterschied zu vielen anderen Sprachen: Python wird trotzdem
benutzt, auch von denen, die sich (wie ich) über die
Whitespace-Sache ärgern.

von Christopher C. (trihexagon)


Lesenswert?

Roland F. schrieb:
> A. K. schrieb:
>> Mit der Qualität der Sprachen hat das nichts zu tun.
>
> Aber womit dann?

Menschen sind oft faul oder nehmen sich nicht mehr die Zeit, sich 
weiterzubilden. Ich bin viel zu vielen Menschen begegnet, die immer noch 
ungarische Notation einsetzten, keine Ahnung von C99 haben und seit dem 
Berufsleben technologisch stehen geblieben sind. (Einer davon ist sogar 
Professor und relativ jung). Oder schau mal ins Gnome/Gtk Lager, die 
machen 2016 GUI-Anwenungen immer noch in C (würg).

Ok und Toolchain/Bibliotheken, also das ganze außen rum, sind bei den 
etablierten Sprachen ziemlich gut. Das macht natürlich auch was aus.

Kaj schrieb:
> Roland F. schrieb:
>> Und warum bekommen sie die nicht? Warum floppen praktisch alle erdachten
>> Sprachen, die die (vermeintlichen?) Schwächen von C und Konsorten
>> abstellen wollen?
> Ich denke Rust ist ein echter Kandidat, gibt es jetzt auch schon fuer
> AVR, bzw. man arbeitet dran.
> https://github.com/avr-rust/rust

Ah sehr schön, kannte ich noch gar nicht.
ARM Cortex geht schon länger, eigentlich schon immer, da der Rust 
Kompiler auf llvm aufsetzt. Da werde ich die nächste Zeit mal was damit 
machen.
https://github.com/japaric/xargo
http://antoinealb.net/programming/2015/05/01/rust-on-arm-microcontroller.html

Kaj schrieb:
> Schau dir doch nur mal die Disskusionen zu Python an, wie viele Leute
> sich an dem Syntaxtischen Whitespace stoeren.

Sowas ist ja auch relativ diskussionswürdig. Das blöde ist, dass 
Leerzeichen und Tabulatoren nicht zu unterscheiden sind. Wie es ständig 
mit YAML Probleme gab oder letztens mit einem Makefile (bei einer Regel 
Leerzeichen statt Tabulator)...

Kaj schrieb:
> Oder Rust:
> Warum muss ich bei einer Variablen extra angeben, dass ich sie
> veraendern koennne moechte? (Also das gegenteil von const in C/C++)
> Ist meiner Meinung nach voelliger Bloedsinn, da man in der Regel wohl >
> 97% aller Variablen veraendern koennen moechte.
>
> Und so faengt es an, mit den Vorurteilen und der Ablehnung. Obwohl ich
> die Sprache bisher nie benutzt habe, habe ich jetzt schon das Vorurteil,
> dass die Sprache mist ist, mag sie auch noch so gute Konzepte enthalten.

Nur ist das, gerade bei Rust, kein Unsinn, sondern hat seine Gründe.
1. In C++ gibts zwar const-correctness, nur wird sie viel zu oft 
vergessen. Das sieht man oft bei fremden Code. Auch ich bekomme es nicht 
hin const-correctness komplett durchzuziehen, einfach weil man schnell 
das const vergisst. Bei Rust ist das nicht so, da bekomme ich es hin, 
weil Variablen automatisch immutable sind und ich sie explizit auf 
mutable setzen muss. Das empfinde ich als Vorteil.

2. Ist es wichtig const-correctness in Rust einzuhalten, da die Sprache 
Aliasing bei veränderbaren Variablen verbietet, um Raceconditions 
unmöglich zu machen (außer natürlich im unsafe Block). Bei Rust liegt 
der Fokus nämlich auch stark auf Nebenläufigkeit. Die Eliminierung von 
Aliasing hat aber auch den Vorteil, dass aggressiver vom Kompiler 
optimiert werden kann.

BTW. 97% sind echt stark übertreiben. Ich hab mal mein Programm 
analysiert, dass Dateien übers Netzwerk überträgt, eine kleine 
Fingerübung um in Rust reinzukommen. 27 Variablen sind immutable und 17 
mutable, also gerade mal ~39%. Viele Variablen sind nämlich nur da, um 
Ergebnisse (z.B. von aufgerufenen Methoden/Funktionen) 
zwischenzuspeichern und werden ausgewertet, aber nie wieder verändert.

Kaj schrieb:
> Dazu kommt, dass fast monatlich eine neue Sprache geboren wird, die
> verspricht, das non plus ultra zu sein, und alles besser zu machen.

Ja weil es unglaublich viele verschiedene Probleme gibt, die es mit 
Programmiersprachen zu lösen gilt. Wenn du aber anfängst zu filtern, 
also den Einsatzbereich einschränkst, fällt dir schnell auf, dass es gar 
nicht so viele sind. Ich meine, wie viele Sprachen sind rausgekommen, 
die sich für Lowlevel-Zeug wie Treiber-/Kernelentwicklung oder µC 
eignen? R nicht, Julia auch nicht. Auch nicht Go (Server), Nimrod? Ne 
auch nicht wirklich. Eigentlich nur Rust und D.

Kaj schrieb:
> Ich wuerde mir echt gerne Rust naeher anschauen, aber bei genauerer
> betrachtung, bringt es mir keinen grossen Mehrwert. Warum?
> Rust ist wie C -> Alles muss man selber von Hand machen.

Bitte was? Das muss dann für C++ ebenfalls gelten. Rust bietet sehr viel 
"zero cost abstraction" Sprachelemente. C hat ja nicht mal Referenzen. 
Speicherverwaltung geht in Rust auch viel komfortabler und vor allem 
sicher! Eine wesentlich mächtigere (optionale!) Standardbibliothek als 
die von C besitzt Rust auch. Also von dem her verstehe ich nicht was du 
damit meinst, dass sich Rust nicht wie Java anfühlt ist klar, aber zu 
Fuß ist was anderes.

Kaj schrieb:
> Auch das ist ein Punkt, wo ich sage: Da nutze ich lieber C, anstatt
> Rust, Julia, Go, oder wie sie nicht alle heissen.

Also Rust und Go sind schon ziemlich stabil. Seit Version 1.0 achten 
beide auf Abwärtskompatibilität und der Sprachkern wird höchstens 
erweitert. Wo es momentan ziemlich heftig ist, ist Swift von Apple.

: Bearbeitet durch User
von Nop (Gast)


Lesenswert?

Christopher C. schrieb:

> 1. So hervorragende Kompiler (gcc, icc...), wie im C/C++ Umfeld, sind
> anderswo eher selten (wenn man mal bei den nativen Sprachen bleibt).

a) Pascal sollte sich sogar noch effektiver compilieren lassen, weil man 
da von vornherein kein Problem mit Aliasing hat, denn Pascal hat eine 
strenge Typisierung. Genau das ist ja auch ein Grund, wieso bei Numerik 
Fortran immer noch überlegen ist.

b) und WARUM gibt es für andere Sprachen nicht so hervorrangende 
Compiler?

> 2. Wie viel Aufwand wurde denn in die Delphi-Variante im Vergleich zu
> den anderen Varianten reingesteckt?

Verkehrte Frage; es geht darum, wieso sich all die anderen, deren 
Engines besser sind, für C/C++ entscheiden haben. Oder man könnte gemein 
sein und folgern, daß C/C++-Programmierer am meisten Mühe in ihr Projekt 
stecken.

> 3. Qualität Algorithmus? (Analog zu Punkt 2.)

C/C++-Programmierer machen also die besten Algorithmen?


Zu der Sache mit syntaktischen Leerzeichen: Das war sinnvoll, als man 
noch mit Lochkarten gearbeitet hat, da kommt das nämlich her. Deswegen 
hat Fortran das, weil es aus dieser Zeit stammt. In Texteditoren ist das 
einfach nur dämlich, sowas zu einzuführen.

von Nop (Gast)


Lesenswert?

Kaj schrieb:

> Wie soll ich mich aber mit einer Sprache hinreichend auseinander setzen,
> wenn es ja fast taeglich eine neue gibt?

Eben.

> Auch das ist ein Punkt, wo ich sage: Da nutze ich lieber C, anstatt
> Rust, Julia, Go, oder wie sie nicht alle heissen.

Zumal, wenn man sich auf die neueste, hipste Modesprache einläßt: wer 
garantiert mir, daß es dafür in 10 Jahren überhaupt noch Compiler gibt? 
Und daß ich nicht am Ende mit dem Projekt in einer Sackgasse stecke? 
C-Compiler wird es auch in 30 Jahren noch geben.

> Darueberhinaus gibt es natuerlich das Problem des Wissens.
> Wie viele C-Programmierer findet man?
> Und wieviele Programmierer findet man zu Rust oder Julia?

Was insbesondere im gewerblichen Einsatz entscheidend ist, Stichwort 
Busfaktor. Es kommt hinzu, daß man als Programmierer weiß, daß es 
haufenweise Projekte gibt, die in C sind, so daß man damit auch gefragt 
ist. Mit der neuesten Modesprache kann man für Hobbies sicher arbeiten, 
aber beruflich?!

C hat noch einen Vorteil - die Sprache ist nicht an das Wohlergehen 
einer bestimmten Firma geknüpft. Insbesondere gibt es sehr gute Tools 
für diverse Plattformen unter Opensource-Lizenzen. Das hat zwei 
Konsequenzen:

a) man gerät nicht in einen vendor-lock-in wie z.B. bei sämtlichen 
Microsoft-Ausgeburten.
b) man wird nicht bleich, wenn die Firma strauchelt. Daß Embarcadero 
gerade dieses Jahr den spanischen Standort dichtgemacht und 80 Leute 
gefeuert hat, ist da ein unangenehmes Beispiel.
c) Oder daß man sich z.B. mit Java heutzutage eine Firma wie Oracle ins 
Boot holt, was man nicht wirklich will.

Zwar ist es embedded auch so, daß schon eine neue Windowsversion dafür 
sorgen kann, daß kommerzielle embedded-Compiler nicht mehr laufen. Vor 
allem wegen wegen Kopierschutzproblemen. Aber sofern man die 
compiler-spezifischen Erweiterungen sauber gekapselt hat, kann man 
notfalls auch auf GCC wechseln, wenn sonst gar nichts mehr geht.

Andere Sprachen mögen besser sein, aber solange ihr Mehrwert nicht die 
Opportunitätskosten für den Wechsel übersteigt, floppen sie. Das ist ein 
Faktor, der im akademischen Elfenbeinturm keine Rolle spielt, in der 
Realität schon. Das wird egerne als "Faulheit" abgetan - bevorzugt von 
denen, die die Opportunitätskosten nicht zu tragen hätten.

von (prx) A. K. (prx)


Lesenswert?

Jobst Q. schrieb:
> In C kann man wegen der Nullterminierung einen String sehr einfach und
> effizient ohne Rumkopieren in mehrere Teilstrings aufteilen, indem man
> Trennzeichen durch '\0' ersetzt. In D ginge das nicht mehr. Toller
> Fortschritt!

Es ist tatsächlich genau andersrum. ;-)

In C muss man umständlich den Originalstring manipulieren, um ihn in 
Teile zu zerlegen. Wenn man das Original nicht verändern darf, muss man 
es vorher kopieren.

In D kann man Substrings direkt als Strings weiterverwenden, ohne 
umständlich Nullen reinzuschreiben. Da dynamische Arrays aus 
Länge+Pointer bestehen, zeigt der Substring direkt in die Daten des 
ursprünglichen Strings.

http://dlang.org/spec/arrays.html

Slicing an array means to specify a subarray of it. An array slice does 
not copy the data, it is only another reference to it. For example:
1
int[10] a;   // declare array of 10 ints
2
int[] b;
3
4
b = a[1..3]; // a[1..3] is a 2 element array consisting of
5
             // a[1] and a[2]

: Bearbeitet durch User
von Carl D. (jcw2)


Lesenswert?

In C++ nennt sich das string_view.

Man darf in konkreten Fall C nicht ankreiden den Original-String zu 
beschädigen.
Das macht im D-Beispiel nämlich eine Änderung an b auch:
" b ist eine Referenz auf a[1..3] "

von (prx) A. K. (prx)


Lesenswert?

Carl D. schrieb:
> Das macht im D-Beispiel nämlich eine Änderung an b auch:

Aber eben erst eine nachträgliche Änderung von b, nicht schon die 
Zerlegung des Strings. In C ändert bereits die Zerlegung selbst den 
Inhalt.

: Bearbeitet durch User
von Carl D. (jcw2)


Lesenswert?

A. K. schrieb:
> Carl D. schrieb:
>> Das macht im D-Beispiel nämlich eine Änderung an b auch:
>
> Aber eben erst eine nachträgliche Änderung von b, nicht schon die
> Zerlegung des Strings. In C ändert bereits die Zerlegung selbst den
> Inhalt.

welcher Teil von "string_view" war denn nicht zu lesen?

von (prx) A. K. (prx)


Lesenswert?

Ich bin grad nicht bei C++, sondern bei C und D. Dass C++ Strings anders 
arbeiten als C Strings ist mir bewusst.

von (prx) A. K. (prx)


Lesenswert?

Man muss in D etwas aufpassen, ob man es mit statischen oder dynamischen 
Arrays zu tun hat. In obigem Beispiel wird
  b = a[1..3];
eine Referenz auf Daten in a produzieren, ein späteres
  b = ...was anderes...;
wird aber nicht den durch b referenzierten Inhalt von a überschreiben, 
sondern die Referenz b auf den neuen Inhalt verweisen lassen. Nur mit
  b[] = ...;
  b[2] = ...;
  b[1..$] = ...;
wird der referenzierte Inhalt geändert.

: Bearbeitet durch User
von Jobst Q. (joquis)


Lesenswert?

Kaj schrieb:
> Warum sich gewisse Sprachen nicht durchsetzen ist einfach: Faulheit.
> Die Faulheit des Menschen, sein gewohntes aufzugeben, etwas neues zu
> lernen, anders zu denken...

So ganz stimmt das nicht. Ich war BASIC gewohnt, als ich C lernte und 
habe es liebend gerne aufgegeben. Gefrustet von der Inkonsistenz 
(unklare Regeln und viele Ausnahmen), den vielen Schlüsselwörtern, die 
oft gleichzeitig Funktionen bzw Aktionen waren, der Umständlichkeit der 
Stringbearbeitung und vielen anderen Ärgernissen, war es eine Befreiung 
und ein Segen, C kennen zu lernen. Mit anderen Worten, eine neue Sprache 
setzt sich durch, wenn es sich lohnt gegenüber der alten.

Das Problem bei neuen Sprachen ist weniger die Faulheit als die 
Erwartungen. Die Vorstellungen, dass es so sein muss, wie man es 
kennengelernt hat. Dass etwas falsch ist, wenn es dann anders ist. Der 
Schritt von der ersten zur zweiten Sprache ist oft der schwerste, wenn 
man die erste Sprache mit dem Programmieren an sich identifiziert.

Falsche Erwartungen sind auch die Ursache der meisten Programmierfehler. 
Wer zB von strncpy erwartet, dass es eine begrenzte Form von strcpy ist, 
wird irgendwann merken, dass er sich getäuscht hat. Denn das Ergebnis 
ist nicht immer ein String wie bei strcpy, sondern bei Überlänge des 
Quellstrings nur ein gefülltes Array, dem zum String die abschließende 
Null fehlt. Dafür wird bei kürzeren Strings der Rest des angegebenen 
Puffers mit Null-Bytes gefüllt, was bis auf die eine Endnull bei Strings 
überflüssig ist. Die Funktion wäre also mit str2array treffender 
benannt.

Das ist aber kein Fehler der Sprache C sondern der Library-Entwickler 
bzw ein Mißverständnis zwischen ihnen und dem Anwender. Zur Vermeidung 
solcher Fehler muss man alle Funktionen und Methoden, die man verwendet, 
genau kennen, am besten den Quelltext. Und die Quelltexte der C-Lib sind 
leichter erhältlich als die von anderen Sprachen.

Wenn man sich die Funktionen selbst schreibt, hat man diese Probleme 
nicht, man kann sie genau so schreiben, wie man sie braucht. Natürlich 
ist das alles "von Hand", aber das ist kein wirkliches Problem. Man muss 
sie ja nicht für jedes Programm neu schreiben. Einmal geschrieben, kann 
man sie tausendfach verwenden.

von Jobst Q. (joquis)


Lesenswert?

A. K. schrieb:
> Jobst Q. schrieb:
>> In C kann man wegen der Nullterminierung einen String sehr einfach und
>> effizient ohne Rumkopieren in mehrere Teilstrings aufteilen, indem man
>> Trennzeichen durch '\0' ersetzt. In D ginge das nicht mehr. Toller
>> Fortschritt!
>
> Es ist tatsächlich genau andersrum. ;-)
>
> In C muss man umständlich den Originalstring manipulieren, um ihn in
> Teile zu zerlegen.

Um zB einen Kommentar abzutrennen, schreib ich s1=split(s,'#'); Dann hab 
ich den String ohne Kommentar in s und den Kommentar in s1. Was ist 
daran umständlich?

Die Funktion selbst ist auch kein Aufwand:

char * split(char *s,char c){
while (*s && *s!=c )s++;
if (*s==c)*s++=0;
return s;
}

> Wenn man das Original nicht verändern darf, muss man
> es vorher kopieren.

Wann braucht man schon mal einen unveränderbaren Originalstring? 
Normalerweise liest man eine Zeile aus einer Datei oder Eingabe in einen 
Puffer, der sowieso mit jeder Zeile wieder neu beschrieben wird. Und 
einen String zu kopieren ist ja auch kein Drama, wenn es mal sein muss.

von Rolf M. (rmagnus)


Lesenswert?

Oliver S. schrieb:
> Mit C ist es wie mit Kochgeräten:
> Thermomix , Backöfenautomatikprogramme, und was es da sonst noch an
> Küchen"helferlein" gibt, oder einfach ein scharfes Messer.
>
> Letzteres ist bei ungeübter Anwendung gefährlich, man muß tatsächlich
> lernen, damit umzugehen. Wenn man es aber kann, ist es unschlagbar
> schnell und flexibel.

Ich denke da an selber kochen vs. Mikrowellen-Essen aufwärmen. Ersteres 
ist mehr Aufwand, und es gibt mehr Möglichkeiten, was falsch zu machen, 
aber wenn man's kann, schmeckt das Ergebnis um Welten besser als das 
Mikrowellen-Futter. ;-)

Christopher C. schrieb:
> Menschen sind oft faul oder nehmen sich nicht mehr die Zeit, sich
> weiterzubilden. Ich bin viel zu vielen Menschen begegnet, die immer noch
> ungarische Notation einsetzten, keine Ahnung von C99 haben und seit dem
> Berufsleben technologisch stehen geblieben sind.

Das liegt meines Erachtens maßgeblich daran, dass Microsoft bei C auch 
auf diesem Level stehen geblieben ist.

> Oder schau mal ins Gnome/Gtk Lager, die machen 2016 GUI-Anwenungen immer
> noch in C (würg).

Das war schon nicht sinnvoll, als sie damit angefangen haben. Ich wollte 
mich mal in die Gtk-Programmierung einlesen, um mich nicht nur auf 
meinen Qt-Horziont zu beschränken. Ich hatte aber ziemlich schnell keine 
Lust mehr darauf. OOP kann man zwar auch zu Fuß in C machen, aber Spaß 
macht das absolut nicht.

Jobst Q. schrieb:
> Die Funktion selbst ist auch kein Aufwand:
>
> char * split(char *s,char c){
> while (*s && *s!=c )s++;
> if (*s==c)*s++=0;
> return s;
> }

Warum nimmst du nicht strtok()?

von Jobst Q. (joquis)


Lesenswert?

Rolf M. schrieb:
> Jobst Q. schrieb:
>> Die Funktion selbst ist auch kein Aufwand:
>>
>> char * split(char *s,char c){
>> while (*s && *s!=c )s++;
>> if (*s==c)*s++=0;
>> return s;
>> }
>
> Warum nimmst du nicht strtok()?

strtok ist wesentlich komplizierter in der Ausführung und der 
Verwendung. Es kann dafür mehrere Trennzeichen auf einmal behandeln, 
aber das habe ich noch nie gebraucht.

von Jobst Q. (joquis)


Lesenswert?

Dazu kommt bei strtok() als Rückgabe der NULL-Pointer, wenn keins der 
Trennzeichen gefunden wurde, was eine extra Fehlerbehandlung zwingend 
erforderlich macht. Mein split() gibt dann einfach das Stringende, also 
einen gültigen Leerstring zurück. Es ist ja nicht gleich ein Fehler, 
wenn eine Zeile keinen Kommentar enthält.

von (prx) A. K. (prx)


Lesenswert?

Rolf M. schrieb:
> Warum nimmst du nicht strtok()?

Das ist eine der C Funktionen mit eingebauter Falltür. So kleinräumig 
angewandt ist sie kein Problem. Aber wenn sowas in dieser Art draus 
wird:
1
  ...
2
  for (char *p = strtok(s1, ","); p; p = strtok(NULL, ","))
3
    f(...);
4
  ...
5
void f(...)
6
{
7
  for (char *q = strtok(s2, " "); q; q = strtok(NULL, " "))
8
    ...
9
}
dann wird man merken, dass strtok ein statisches Gedächtnis hat und das 
innere strtok(s2,..) die statische Information des äusseren 
strtok(s1,..) verwirft.

: Bearbeitet durch User
von Rolf M. (rmagnus)


Lesenswert?

A. K. schrieb:
> dann wird man merken, dass strtok ein statisches Gedächtnis hat und das
> innere strtok(s2,..) die statische Information des äusseren
> strtok(s1,..) verwirft.

Dafür gibt's dann strtok_r, wo diese Information beim Aufrufer 
gespeichert wird. Natürlich macht das die Anwendung noch etwas 
umständlicher.
Was mich eher an strtok() gestört hat (bzw. dazu geführt hat, dass ich 
es meistens nicht nutzen kann) ist, dass es das Auftreten zweier direkt 
aufeinanderfolgender Delimeter nicht richtig behandelt. Statt dann einen 
leeren String zurückzugeben, überspringt es das einfach. Also kommt bei 
"a;b;;c" nur "a", "b" und "c" und nicht, wie ich es eigentlich praktisch 
immer brauche "a", "b", "" und "c".
Beim Parsen von NMEA oder von CSV-Daten ist das ziemlich blöd, denn da 
können leere Elemente durchaus vorkommen, müssen aber berücksichtigt 
werden, weil sonst der Rest der Zeile falsch einsortiert wird.

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


Lesenswert?

Rolf M. schrieb:
> Was mich eher an strtok() gestört hat (bzw. dazu geführt hat, dass ich
> es meistens nicht nutzen kann) ist, dass es das Auftreten zweier direkt
> aufeinanderfolgender Delimeter nicht richtig behandelt.

"Richtig" ist das, was in der Doku steht. Insofern passt es.

> Beim Parsen von NMEA oder von CSV-Daten ist das ziemlich blöd, denn da
> können leere Elemente durchaus vorkommen, müssen aber berücksichtigt
> werden, weil sonst der Rest der Zeile falsch einsortiert wird.

Klar. Nur hatte man bei strtok wohl eher PATH im Auge gehabt. Oder 
Leerzeichen, die ja auch mal im Rudel auftreten können. NMEA oder CSV 
gab es damals noch nicht.

von Rolf M. (rmagnus)


Lesenswert?

A. K. schrieb:
> "Richtig" ist das, was in der Doku steht. Insofern passt es.

Dann lass mich "richtig" durch "sinnvoll" ersetzen.

>> Beim Parsen von NMEA oder von CSV-Daten ist das ziemlich blöd, denn da
>> können leere Elemente durchaus vorkommen, müssen aber berücksichtigt
>> werden, weil sonst der Rest der Zeile falsch einsortiert wird.
>
> Klar. Nur hatte man bei strtok wohl eher PATH im Auge gehabt. Oder
> Leerzeichen, die ja auch mal im Rudel auftreten können. NMEA oder CSV
> gab es damals noch nicht.

Wobei es bei einem strtok(), das auch leere Elemente zurückgibt, ein 
leichtes wäre, diese selber zu ignorieren. Mit einem strtok, das das 
schon von sich aus tut, kann man leider gar nichts anfangen, wenn man 
diese leeren Elemente braucht. Somit wäre ersteres eigentlich flexibler 
gewesen.

Übrigens gibt's NMEA schon seit 1983, also immerhin 6 Jahre länger als 
die ANSI-Version von C.

: Bearbeitet durch User
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.