Einen schönen guten morgen,
ich habe eine Frage bezüglich eurer Umsetzung von TRUE und FALSE. Wie
macht ihr dies?
normalerweise sehe ich dafür defines
1
#define FALSE (0)
2
#define TRUE (!FALSE)
hier zeigt es sich ja auch, dass TRUE und FALSE eigentlich mindestens
ein unit8 ist. Hier sehe ich das Problem aber, dass man TRUE keine
variable zuordnen kann
1
boolx;
2
x=TRUE;
was genau ist jetzt x? kann ja alles (außer 0) sein.
jetzt habe ich letztens noch ein anderes define gesehen
1
#define TRUE (1==1)
2
#define FALSE (1!=1)
wie genau ist denn hier der typ?
jetzt kann ich aber schreiben
1
x=TRUE
(so sehe ich es zumindest).
Was hat welche vor-/nachteile?
Wie kommt es, dass man doch meistens die erstere variante sieht?
Felix schrieb:> jetzt habe ich letztens noch ein anderes define gesehen> #define TRUE (1==1)> #define FALSE (1!=1)
Das ist die einzig richtige Definition, weil du hierbei dem Compiler
keine Vorgaben machst.
Bei deiner ersten Formulierung könntest du genauso #define FALSE (1)
schreiben und würdest damit aber böse auf die Nase fallen, obwohl die
Definition für TRUE und FALSE in sich konsistent wäre.
Kurz: Deine erste Variante taugt nichts.
A. S. schrieb:> Was ist an (0) und (1) bzw (!0) falsch?
Du musst Vorwissen darüber reinstecken, was dein
Compiler/Programmiersprache als true erkennt. Bei der Variante "#define
TRUE (1==1)" musst du selber nichts über die Umsetzung von true und
false im Compiler wissen.
Felix schrieb:> Einen schönen guten morgen,>> ich habe eine Frage bezüglich eurer Umsetzung von TRUE und FALSE. Wie> macht ihr dies?> normalerweise sehe ich dafür defines> #define FALSE (0)> #define TRUE (!FALSE)>> hier zeigt es sich ja auch, dass TRUE und FALSE eigentlich mindestens> ein unit8 ist.
Sie sind vom Typ int.
> Hier sehe ich das Problem aber, dass man TRUE keine> variable zuordnen kann> bool x;> x = TRUE;
Warum nicht?
> was genau ist jetzt x? kann ja alles (außer 0) sein.
Nein. Es ist genau 1. Der Operator ! liefert bei 0 eine 1 zurück, bei
allem anderen eine 0. Du hättest also genau so gut auch
1
#define TRUE 1
schreiben könnnen.
> jetzt habe ich letztens noch ein anderes define gesehen> #define TRUE (1==1)> #define FALSE (1!=1)> wie genau ist denn hier der typ?
Genau das gleiche wie oben. TRUE ist ein int mit dem Wert 1, FALSE ist
ein int mit dem Wert 0.
> Was hat welche vor-/nachteile?
Alle Varianten haben den Nachteil, dass sie unnötig umständlich
formuliert sind und vermutlich aus falschem Verständnis der Sprache
entstanden sind.
Außerdem haben sie den Nachteil, dass sie nicht die
Standard-Implementation sind. Warum nicht einfach ein #include
<stdbool.h>?
Wolfgang schrieb:> Felix schrieb:>> jetzt habe ich letztens noch ein anderes define gesehen>> #define TRUE (1==1)>> #define FALSE (1!=1)>> Das ist die einzig richtige Definition, weil du hierbei dem Compiler> keine Vorgaben machst.
Blödsinn. Jeder Ausdruck hat einen Typ und einen Wert.
> Kurz: Deine erste Variante taugt nichts.
Die Varianten taugen alle nichts, weil sie von falschen Voraussetzungen
ausgehen.
A. S. schrieb:> Wolfgang schrieb:>> weil du hierbei dem Compiler keine Vorgaben machst.>> Was bedeutet das?
Daß Wolfgang mal wieder Unsinn schreibt und wichtig tut.
> Was ist an (0) und (1) bzw (!0) falsch?
Erstens braucht man bei einfachen Zahlen in einem #define KEINE Klammer,
die braucht man nur bei Formeln.
#define TRUE 1
ist falsch, denn true ist in C jede Zahl ungleich Null. Also schreibt
man das auch exakt so hin. Ende der Philosohpiestunde.
#define TRUE !FALSE
Auch hier braucht es keine Klammern, denn der unäre Operator bindet sehr
stark an das Argument, hier !0.
bei x = TRUE
ist das Ergebnis zwar abhängig vom Zahlentyp, aber es ist trotzdem immer
TRUE.
Felix schrieb:> hier zeigt es sich ja auch, dass TRUE und FALSE eigentlich mindestens> ein unit8 ist. Hier sehe ich das Problem aber, dass man TRUE keine> variable zuordnen kann>
1
>boolx;
2
>x=TRUE;
Welchen Sinn soll die Fragestellung denn haben? Wenn man einen
Variablentyp "bool" zur Verfügung hat, braucht man doch gar keine eigene
Definition für TRUE und FALSE mehr. Das war ein Hilfskonstrukt, welches
man verwendet hat bevor boolsche Variablen in den C-Sprachstandard
aufgenommen wurden.
Falk B. schrieb:> #define TRUE 1>> ist falsch, denn true ist in C jede Zahl ungleich Null. Also schreibt> man das auch exakt so hin.
Man kann "jede Zahl ungleich Null" aber nicht hinschreiben. Wie ich
schon sagte: Jeder Ausdruck hat einen Wert. Einen, nicht mehrere
gleichzeitig. Auch dann nicht, wenn es sich um einen Vergleich handelt.
Falk B. schrieb:> Alles ungleich 0 ist TRUE!
Nur bei Vergleichen.
Der Standard nutzt immer 1 als true Wert bei Zuweisungen.
Nimm stdbool.h dann bleibt alles kompatibel.
Falk B. schrieb:> Rolf M. schrieb:>> Genau das gleiche wie oben. TRUE ist ein int mit dem Wert 1, FALSE ist>> ein int mit dem Wert 0.>> FALSCH!!!
Nein!
> Alles ungleich 0 ist TRUE!
Wenn man einen Integer als booleschen wert verwendet, stimmt das. Aus
jedem Zahlenwert außer 0 wird dann true. Aber nicht in umgekehrter
Richtung. Wenn man aus einem booleschen Wert einen int macht, kommt für
true immer 1 raus. Wie gesagt: Ein Ausdruck kann nicht mehrere Werte
gleichzeitig annehmen. Es muss immer genau ein Wert sein, und der ist in
diesem Fall auf 1 festgelegt.
Oder nochmal als praktisches Beispiel. Das #define ist einfach nur
Textersetzung. Wenn man also schreibt
1
if(x==TRUE)
dann wird der Präprozessor daraus
1
if(x==!0)
machen. Was kommt da jetzt raus, wenn x den Wert 5 hat? Springt er in
das if? Natürlich nicht, denn !0 hat nicht den Wert 5. Wenn du mir nicht
glaubst, probiere es einfach mal aus.
Rolf M. schrieb:> Nein. Es ist genau 1. Der Operator ! liefert bei 0 eine 1 zurück, bei> allem anderen eine 0. Du hättest also genau so gut auch#define TRUE 1> schreiben könnnen.
Dann sieh dir mal an, was passiert, wenn du schreibst:
Wolfgang schrieb:> Was erwartest du am Ende für y?
Ich erwarte den Wert 1. Den erwarte ich aber auch bei allen anderen hier
vorgestellten Varianten von Definitionen von TRUE. Auch an dich:
Probiere es einfach mal aus.
Rolf M. schrieb:>> Was erwartest du am Ende für y?>> Ich erwarte den Wert 1. Den erwarte ich aber auch bei allen anderen hier> vorgestellten Varianten von Definitionen von TRUE.
Dort liegt dein Problem. Die Definition von TRUE muss auch beim
Vergleich funktionieren. Das tut sie hier aber nicht! Die Zuweisung ist
trivial. Da kann man auch
#define TRUE 42
schreiben!
Falk B. schrieb:> Rolf M. schrieb:>>> Was erwartest du am Ende für y?>>>> Ich erwarte den Wert 1. Den erwarte ich aber auch bei allen anderen hier>> vorgestellten Varianten von Definitionen von TRUE.>> Dort liegt dein Problem. Die Definition von TRUE muss auch beim> Vergleich funktionieren. Das tut sie hier aber nicht!
Das ist nicht mein Problem, sondern eures. Denn das gilt nicht nur für
#define TRUE 1, sondern ausnahmslos für alle möglichen Definitionen von
TRUE außer #define TRUE _True.
Falk B. schrieb:> x=3;> if (x==TRUE)> Dort liegt dein Problem. Die Definition von TRUE muss auch beim> Vergleich funktionieren. Das tut sie hier aber nicht!
Beim Vergleich müssen beide Werte den gleichen Typ haben. x ist ein
Integer, daher wird TRUE in einen integer umgewandelt. Das ergibt:
> if (3==1)
Wie jede andere auch, hat die Programmiersprache C einige
Überraschungen, die man als Anfänger so nicht erwartet.
Stefan ⛄ F. schrieb:> Beim Vergleich müssen beide Werte den gleichen Typ haben. x ist ein> Integer, daher wird TRUE in einen integer umgewandelt.
In den obigen Defintionen ist TRUE bereits ein Integer.
Hier der Auszug aus dem C-Standard zum Vergleich:
The == (equal to) and != (not equal to) operators are analogous to the
relational operators except for their lower precedence. Each of the
operators yields 1 if the specified relation is true and 0 if it is
false. The result has type int.
Heißt also,
1
#define TRUE (1==1)
ist 100% äquivalent zu
1
#define TRUE 1
Und hier zum !-Operator:
The result of the logical negation operator ! is 0 if the value of its
operand compares unequal to 0, 1 if the value of its operand compares
equal to 0. The result has type int.
The expression !E is equivalent to (0==E).
Und das bedeutet, dass
1
#define TRUE (!FALSE)
ebenfalls 100% äquivalent zu
1
#define TRUE 1
ist.
Es gibt hier keinen Spielraum für den Compiler!
MaWin schrieb:> Schon recht peinlich, was hier alles behauptet wird.
Vor allem, weil man es mit einem Compiler so leicht mal selbst
ausprobieren könnte.
Rolf M. schrieb:> Ich erwarte den Wert 1. Den erwarte ich aber auch bei allen anderen hier> vorgestellten Varianten von Definitionen von TRUE. Auch an dich:> Probiere es einfach mal aus.
Dann erkläre mal jemandem mit ein bisschen logischen Grundkenntnisen,
warum x=3 als zwar als true erkannt wird, aber der Vergleich von x mit
TRUE kein true liefert.
Vielleicht werden hier ja verschiedene Bereiche von True durcheinander
geworfen:
Als #define: Da werden 1, !0, (1==1) oder (1>0) ALLE als 1 umgesetzt.
Punkt. Wer da einen Unterschied postuliert, sollte einen Dreizeiler
posten. Von Konstruktion mit # und ## jetzt mal abgesehen.
Dass eine Abfrage (if, for, while, ?) als "wahr" betrachtet wird, wenn
ihr Wert 42 ist, hat damit nichts zu tun: Dass haben die Schöpfer
umfassend festgelegt und beschrieben. 42 ist nicht 1. Aber (42==0) ist
1.
Und dass man auf TRUE nicht abfragen darf (x==TRUE) sollte man
irgendwann halt wissen.
A. S. schrieb:> Und dass man auf TRUE nicht abfragen darf (x==TRUE) sollte man> irgendwann halt wissen.
Das sollte ein vernünftiger Compiler überhaupt nicht zulassen und sich
mit einer dicken Fehlermeldung beschweren.
Da kommen die Krücken aus den 70er Jahren zum Vorschein.
Wolfgang schrieb:> Dann erkläre mal jemandem mit ein bisschen logischen Grundkenntnisen,> warum x=3 als zwar als true erkannt wird, aber der Vergleich von x mit> TRUE kein true liefert.
Ich hab ja schon gleich zu Anfang geschrieben, dass die oben
vorgestellten Definitionen von TRUE alle Murks sind. Und das hab ich
genau deshalb, weil die alle darüber hinweg täuschen können, dass es
eben genau so ist, wie du hier beschreibst. Egal wie du dein TRUE
definierst, dieses Problem bleibt bestehen.
Die Gründe, warum das so ist, hab ich eigentlich auch schon genannt.
Jeder Ausdruck hat genau einen Wert. Der Ausdruck (1==1) und der
Ausdruck (!0) können also gar nicht "alles außer 0" als Wert haben.
Daher ist es so gelöst: Wenn ich einen int als booleschen Wert verwende,
wird daraus immer false für 0 und true für alles andere. Wenn ich
umgekehrt aus einem booleschen Wert einen int mache, bekommt der den
Wert 0 für false und 1 für true.
A. S. schrieb:> Und dass man auf TRUE nicht abfragen darf (x==TRUE) sollte man> irgendwann halt wissen.
p.s.
Die explizite Abfrage auf TRUE kann man schnell übersehen, ohne jemals
ein TRUE verwendet zu haben. Der große Käse in C ist, dass Boolschen
Abfragen auf jede beliebige Integervariable zulässig sind:
Wolfgang schrieb:> Der große Käse in C ist, dass Boolschen Abfragen auf jede beliebige> Integervariable zulässig sind
Das kommt letztendlich auch daher, dass es vor C99 gar keinen eigenen
Typ für boolesche Werte gab. Die mussten deshalb als int dargestellt
werden - mit den bereits genannten Regeln. Heute gibt es per #include
<stdbool.h> zwar einen eigenen echten bool-Typ, der tatsächlich nur die
beiden Werte true und false annehmen kann, aber die Sprache wurde aus
Kompatibilitätsgründen nicht konsequent darauf umgebaut.
A. S. schrieb:> Aber (42==0) ist 1.
Sorry, (42!=0) ist 1.
Wolfgang schrieb:> Das sollte ein vernünftiger Compiler überhaupt nicht zulassen und sich> mit einer dicken Fehlermeldung beschweren.> Da kommen die Krücken aus den 70er Jahren zum Vorschein.
Das kann ein Compiler nicht anmeckern, weil es ja um Deine Definition
von TRUE geht. Natürlich meckert er, wenn er bool supportet und Du
Warnungen einschaltest.
Wolfgang schrieb:> warum x=3 als zwar als true erkannt wird, aber der Vergleich von x mit> TRUE kein true liefert.
weil x nicht FALSE ist. Bei binären Gruppierungen ist das zwangsläufig
so, dass es bei mehr als 2 Möglichkeiten keine 1-1 Zuordnung gibt.
Wenn Du 150km/h als "schnell" ansiehst, und 30km/h als "langsam", dann
wirst Du nicht postulieren, dass "schnell" immer 150km/h bedeutet.
Hier ist die Grenze halt nicht 100 (oder so), sondern 0 und != 0.
Ein Auto steht bei 0km/h, es fährt bei !=0km/h. Trotzdem fährt nicht
jedes Auto 1km/h.
Rolf M. schrieb:> In den obigen Defintionen ist TRUE bereits ein Integer.
Mag sein, aber selbst wenn es kein Integer wäre, würde sein Vergleich
fehlschlagen.
In der JS-Welt spricht man von falsy-Werten und truthy-Werten in
Abgrenzung zu den eigentlichen Werten von false und true. Dann wird das
hier besprochene viel klarer.
LG, Sebastian
Wolfgang schrieb:> Da kommen die Krücken aus den 70er Jahren zum Vorschein.
Die Profis, die für sich C entwickelt haben, konnten halt damit umgehen.
Das in den 90er dann auch die Amateutre mit C anfangen, konnte doch
keiner Ahnen - warum sollten die auch Zugang zu den wenigen Computern
bekommen.
Dumme Frage.
Wieso definiert ihr ein Zustand den der Compiler eh als Festen Wert drin
hat ?
Wenn ich sagt : Zustand = True , dann ist mir der Hintergrund der Logik
(ob 0 oder -1) völlig egal. Ich weiß das ich Zustand TRUE (wahr)
zugewiesen habe.
Hat jedenfalls die letzten ca. 30 Jahre gut geklappt. ;)
Schlaumaier schrieb:> Zustand = True , dann ist mir der Hintergrund der Logik> (ob 0 oder -1) völlig egal.
Und wenn dir diese Logik einen Zustand übergibt, wie bestimmst du dann
dessen Wert (true | false)?
Natürlich muss man wissen, was true | false ist.
not true schrieb:> das funktioniert dann nicht mal mit den Libs-Funktionen> #define TRUE 1> char ch = 'a';> if (isalpha (ch) == TRUE)
Da ist wieder der böse Vergleich mit TRUE.
char ist auch nur ein Ganzzahlwert (s.o.)
Echt langweilig....
An die 50 Jahre Streit über bool Values in C
Historisches C kennt Bool nur als impliziten Datentype
False entspricht 0 und alles andere ist True
Es gibt keinen Datentype in historischem C welcher das true abbilden
kann.
Also ist es schon im Ansatz unmöglich ein True zu definieren.
Damit ist der Vergleich irgendwas==true grundsätzlich falsch, bzw.
bietet das Potential für Fehler.
Selbst in modernem C/C++ mit _Bool ist das noch ein Drama.
Denn bei einem == Vergleich int bool wird der bool implizit zu int
aufgeweitet
not true schrieb:> isalpha (ch)
Das ist es ja. isalpha gibt nicht bool zurück sondern int. Und im
Wahr-Fall auch nicht den Wert Wahr (true/TRUE), sondern einen wahren
Wert (non-zero), eben ein "truthly". Um wahre Werte zu erkennen *darf
man nicht* mit Wahr vergleichen.
Und es ist auch m.M.n. besser, falsche Werte nicht durch Vergleich mit
Falsch (oder 0 oder NULL) zu erkennen. Das ist aber für einige
kryptisch.
LG, Sebastian
not true schrieb:> Und wenn dir diese Logik einen Zustand übergibt, wie bestimmst du dann> dessen Wert (true | false)?
Entweder der Wert wird mir TRUE o. False übergeben, dann frage ich ihn
nach den definierten Werten des Compiler ab, oder der Wert wird mir als
Zahl übergeben, dann frage ich ihn als Zahl ab.
So einfach ist es. Oder anders Gesagt : Das Objekt bestimmt was es haben
will nicht ich. Ich bin halt ein Demokratischer Programmierer. Da
dürfen die Objekte etwas mitreden.
Teo D. schrieb:> Nach dem Motto "Keine Arme, keine Kekse". :D
Nö. Nach den Motto "Was seit Ewigkeiten funktioniert hat, muss man nicht
ändern". Computer funktionieren im Grundsatz immer noch mit 0 + 1. Also
wieso was neues machen.
Aber das ist ja üblich inzwischen. Die Programmieren beschäftigen sich
mit so ein Mist, und können nur noch Grafik ändern.
Habe ich die Nacht am neuen Firefox gemerkt. Haben 40 min. gebraucht bis
das wieder lief und vernünftig aussah, und mein Ordnersymbol in der
Symbolleiste wieder schön gelb + Gefüllt war, und die Symbolleiste
wieder da war wo sie hingehört. Bin mal gespannt wie sie das neue Win-10
versaut haben. ?!?! ;)
Arduino Fanboy D. schrieb:> Damit ist der Vergleich irgendwas==true grundsätzlich falsch, bzw.> bietet das Potential für Fehler.
Und sinnlos doppelt gemoppelt.
Arduino Fanboy D. schrieb:> if(testval == irgendwas) /?> if(testval == (_Bool)irgendwas) /!
if(testval) /!
Teo D. schrieb:> if(testval) /!
Wenn irgendwas und testval denn Konstanten wären, könnte man ganz auf
das if() verzichten.
Sind sie aber nicht, und das mit Absicht.
Ihr könnt TRUE und FALSE nicht in eine Sprache reinzwängen, die den Typ
Bool nicht kennt. Ein Define ist hier nur eine Krücke, für diejenigen,
die von einer anderen Sprache als C kommen und/oder C nicht verstehen.
Diese Krücke ist leider nur ein einfacher Stock, mit dem Anfänger leicht
ins Straucheln kommen. Daher am besten nicht mit TRUE und FALSE
arbeiten.
1
if(taste_gedrueckt()){}
2
if(!taste_gedrueckt()){}
braucht kein TRUE oder FALSE. Das würde eher den Lesefluss stören. Eine
Programmiersprache ist vor allem für den Menschen, nicht für den
Computer.
Auch wenn die Funktion bei gedrückter Taste einen Wert ungleich 0 -
beispielsweise einen Tastencode - können die If-Anweisungen so
funktionieren.
Christian H. schrieb:> Ihr könnt TRUE und FALSE nicht in eine Sprache reinzwängen, die den Typ> Bool nicht kennt.
Das absolut abschaummäßige an C ist je gerade, dass es schon immer einen
bool-Typ kannte (nämlich für alle conditionals), aber eben keinen für
den User bereitgestellt hat.
Und die ab C99 erfolgte Bereitstellung dieses Typs ist aus
"Kompatibilitätsgründen" nur halbgar.
U.a. deswegen (aber bei Weitem nicht nur deswegen) ist C eine
Scheiß-Sprache.
Hier wurden alte Zöpfe viel zu lange "aus Kompatibilitätsgründen"
mitgeschleppt. Das macht die Sprache zu einer Sprache mit vielfach
"überraschendem" Verhalten und damit eigentlich vollkommen untauglich.
Wobei: mit C99-Unterstzung sollte ja immerhin folgendes möglich sein:
if ((bool)irgendeinint == true) ...
Ich weiß nicht, ob das wirklich funktioniert, habe auch keinerlei Lust,
das zu testen. Aber wenn es nicht funktieren würde, wäre C eine NOCH
beschissenere Sprache, als sie nachweislich schon ist, denn in jeder
ernstzunehmenden Sprache würde man mit gutem Recht erwarten können,
DASS das funktioniert...
Arduino Fanboy D. schrieb:> Teo D. schrieb:>> if(testval) /!>> Wenn irgendwas und testval denn Konstanten wären, könnte man ganz auf> das if() verzichten.> Sind sie aber nicht, und das mit Absicht.
Ubs
if ((testval) == (irgendwas))
c99 und boole, da darf der Compiler das in einem Bitfeld zusammen
fassen. Naja, zumindest bei XC. Sonnst sähe ich da keinen echten Grund,
irgendwo boole zu verwenden.
Falk B. schrieb:> Rolf M. schrieb:>> Genau das gleiche wie oben. TRUE ist ein int mit dem Wert 1, FALSE ist>> ein int mit dem Wert 0.>> FALSCH!!!>> Alles ungleich 0 ist TRUE!
Du polterst mal wieder.
Schreib lieber "bei Vergleichen gilt in C alles als true, was nicht 0
ist".
1 ist true. Punkt.
W.S.
c-hater schrieb:> abschaummäßige> Scheiß-Sprache> beschissenere Sprache
Zusammengefasst: Du möchtest nicht ernst genommen werden. Deine Wortwahl
ist diesbezüglich mal wieder eindeutig.
Sebastian schrieb:> Und es ist auch m.M.n. besser, falsche Werte nicht durch Vergleich mit> Falsch (oder 0 oder NULL) zu erkennen. Das ist aber für einige> kryptisch.
...und es zeigt sehr schön, wie die formale mit der inhaltlichen Seite
durcheinandergewürfelt werden kann!
Gruß Rainer
Rainer V. schrieb:> ...und es zeigt sehr schön, wie die formale mit der inhaltlichen Seite> durcheinandergewürfelt werden kann!> Gruß Rainer
Ich meine beides. Mich grausen diese Konstrukte "if
(shitHasHitTheFan==0) {...}" oder "if (shitHasHitTheFan==FALSE) {...}".
Die Alternative "if (!shitHasHitTheFan) {...}" fängt alle Falsy-Werte ab
und ist kürzer.
Aber ich benutze im Zweifel auch mal !! um ein Truthy in eine 1 zu
wandeln ...
LG, Sebastian
Frank M. schrieb:> Merkwürdigerweise gibt das Programm exakt "1" aus und nicht "jede Zahl> ungleich Null".
Binär gesehen, IST das jede andere Zahl.
Nur True/False als Zahlen-Wert anzusehen, ist halt grundsätzlich falsch.
Frank M. schrieb:> Ich persönlich schreibe deshalb>> #define TRUE 1> denn eine klare Tatsache umständlich zu verschleiern ist nicht> zielführend.
Warum verschleierst du es dann?
Tust so, als wäre true gleich 1
Dabei ist es das doch gar nicht, sondern 1 wird zu true ausgewertet.
Und das ist ganz was anderes, als du da geschrieben hast.
Dann könntest du genauso gut schreiben
> #define TRUE 4711
Das ist im Prinzip genauso wahr wie
> #define TRUE 1
...noch einfacher brauchts doch nur eine (System-)Konstante mit Wert =
0. Das weist du der Konstanten FALSE zu. Wenn eine Funktion einen
Wahrheitswert verlangt, dann ist alles wahr, was nicht "FALSE" ist. Dazu
braucht es den tatsächlichen Wert von TRUE eben nicht! Wer dann trotzdem
noch Gehirnakrobatik betreiben muß...von mir aus :-)
Gruß Rainer
Rainer V. schrieb:> Wenn eine Funktion einen> Wahrheitswert verlangt, dann ist alles wahr, was nicht "FALSE" ist. Dazu> braucht es den tatsächlichen Wert von TRUE eben nicht!
Meinst du das so?
Arduino Fanboy D. schrieb:> Dann könntest du genauso gut schreiben> #define TRUE 4711> Das ist im Prinzip genauso wahr wie> #define TRUE 1
Ich benutze TRUE und FALSE nie in Abfragen (z.B. if), sondern lediglich
in Zuweisungen.
Beispiel:
1
value=TRUE;
2
....
3
if(value)
4
{
5
...
6
}
7
...
8
// oder auch mal
9
value=FALSE;
10
....
11
if(!value)
12
{
13
...
14
}
15
...
Von daher wäre es tatsächlich vollkommen schnuppe, ob ich TRUE als "1"
oder als "4711" definiere.
Ich schreibe aber trotzdem
1
#define TRUE 1
weil der Compiler Wahrheitswerte (wie x == y) zu 0 oder 1 (und eben
nicht zu 4711) evaluiert.
https://de.wikipedia.org/wiki/Therac-25#Programmfehler
"Ein weiterer Softwarefehler war, dass ein Flag, das die Notwendigkeit
einer Positionsprüfung der Drehscheibe, auf der auch das Wolframtarget
angebracht ist, anzeigte, während einer Einstellungsphase nicht auf
einen festen Wert ungleich 0 gesetzt, sondern ständig erhöht wurde.
Dieses Flag war in einer 8-Bit-Variable abgelegt, hatte also nach jeder
256. Erhöhung wegen Überlauf den Wert 0."
AUTSCH!
Das Problem ist und bleibt nun mal, das C nicht zwischen logischem und
bitweisem Gleich unterscheidet. Um einen funktionierenden Vergleich mit
TRUE bei Prüfung auf logische Gleichheit zu erreichen, müsste einen
impliziter Type Cast der anderen Variablen auf bool stattfinden, um aus
truely ein true zu macht. Dann würde der Vergleich so funktionieren, wie
ihn jeder Nicht-C-Programmierer logischerweise erwarten würde.
Wolfgang schrieb:> Das Problem ist und bleibt nun mal, das C nicht zwischen logischem und> bitweisem Gleich unterscheidet.
Welche Sprache tut das denn?
Das Problem ist eher, dass C nicht von Anfang an einen eigenen bool-Typ
hatte und dass zu viele implizite Konvertierungen stattfinden.
> Um einen funktionierenden Vergleich mit TRUE bei Prüfung auf logische> Gleichheit zu erreichen, müsste einen impliziter Type Cast der anderen> Variablen auf bool stattfinden, um aus truely ein true zu macht. Dann> würde der Vergleich so funktionieren, wie ihn jeder Nicht-C-Programmierer> logischerweise erwarten würde.
Ich denke nicht, dass viele Nicht-C-Programmierer erwarten würden, dass
so etwas wie (3 == true) auch wieder true ergibt. Sie würden viel mehr
erwarten, dass der Compiler mit Fehler abbricht, weil zwei inkompatible
Typen verglichen werden.
Falk B. schrieb:> AUTSCH!
Die haben so ziemlich alles falsch gemacht, scheint mir:
Softwareentwicklung
Die Software wurde von einem einzelnen Softwareentwickler geschrieben –
unter Verwendung vorhandener Teile, deren Programmierer nicht mehr für
die Firma arbeiteten. Der Entwickler war zugleich für Tests zuständig.
Qualitätssicherung
AECL hatte reiche Erfahrung mit Sicherheitsabschätzungen und die
notwendigen Analysen wurden mit gegebener Sorgfalt durchgeführt. Sie
ignorierten aber völlig, dass Software fehlerhaft sein kann.
Rolf M. schrieb:> Die haben so ziemlich alles falsch gemacht, scheint mir:
Ja, klingt gruselig, und das bei Medizintechnik und einer derartigen
Röntgen/Elektronenquelle! ICH hätte da echt Angst und würde alles
doppelt und dreifach sichern, u.a. mit HARDWARE, so wie es im Vorgänger
ja auch der Fall war. Ein tragischer Fall, wenn gleich nicht der letzte,
von Leichtsinn und Technikgläubigkeit! Aber nichts ist unnütz, es kann
(und MUSS!) auch als schlechtes, warnendes Beispiel dienen.
Hab ich da gerade ein leises Flüstern von "767 MAX" gehört . . . .?
Frank M. schrieb:> Ich benutze TRUE und FALSE nie in Abfragen (z.B. if), sondern lediglich> in Zuweisungen.
Nun ja, DAS habe ich noch ie gemacht und es ist auch SEHR verwirrend,
wenn man TRUE/FALSE zuweisen kann, aber nicht immer eindeutig mit TRUE
vergleichen kann. Ich hab TRUE/FALSE so gut wie nie verwendet und immer
nur manuell 0/1 in Variabeln geschrieben und diese normal per
C-Convention auf Ausdruck bzw !Ausdruck getestet, wie in deinem
Beispiel. Damit ist es wenigstens konsistent. Aber das ist am Ende nur
einer der vielen Fallstricke von C . . .
Rolf M. schrieb:> Ich denke nicht, dass viele Nicht-C-Programmierer erwarten würden, dass> so etwas wie (3 == true) auch wieder true ergibt.
Wenn der Wert einer Variablen x als "true" bewertet wir, erwartet jeder
Nicht-C-Programmierer mit ein bisschen Logikverständnis, dass (x==true)
auch als "true" bewertet wird (Beispiel s.o.). Das sind Grundaussagen
der Boolschen Algebra.
Wolfgang schrieb:> Dann sieh dir mal an, was passiert, wenn du schreibst:
Falk B. schrieb:> Hab ich da gerade ein leises Flüstern von "767 MAX" gehört . . . .?
Beim Flüstern steigt halt schon mal die Fehlerrate bei der Übertragung
;-)
Wolfgang schrieb:> Wenn der Wert einer Variablen x als "true" bewertet wir, erwartet jeder> Nicht-C-Programmierer mit ein bisschen Logikverständnis, dass (x==true)> auch als "true" bewertet wird (Beispiel s.o.). Das sind Grundaussagen> der Boolschen Algebra.
Du meinst BASIC Programmierer von 1978! Der Rest, hält diesen Ausdruck
für Schwachsinnig.
Falk B. schrieb:> Ich hab TRUE/FALSE so gut wie nie verwendet und immer> nur manuell 0/1 in Variabeln geschrieben
JA/NEIN, AN/AUS, ... Gefällt mir persönlich besser. Aber bei mir, rede
ja auch keiner mit rein. Und die Löcher in den Knieehen, hab ich mir
alle selbst gebohrt. :)
Falk B. schrieb:> aber nicht immer eindeutig mit TRUE vergleichen kann. I
Dieses Problem wurde schon vor 2000 Jahren abschließend behandelt im
alten Griechenland.
Eine Aussage (oder Frage) kann wahr oder falsch sein. Z.b. X==5.
Es macht aber keinen Sinn, zu fragen, ob diese Aussage/Frage war ist:
(X==5)==wahr.
Wenn ich nun dafür eine Variable habe, Y=(X==5), dann ist Y die
Aussage/Frage. Und es macht natürlich immer noch keinen Sinn, Y nochmals
mit wahr oder falsch zu vergleichen. Y selber ist schon wahr oder nicht.
Auf der Arbeit werde ich bei Konfigurationsparametern immer gefragt, ob
es 0/1 oder true/false heißen soll und wie es um die
Groß/Klein-Schreibung steht. Denn meistens ist es egal, aber eben nicht
immer. Das ist so lästig, man hätte es einfach bei 0/1 belassen sollen.
Nur so al Ergänzung am Rande:
_Bool ist in C ein eigener Datentyp (Native Type). Man braucht dafür
nicht stdbool.h includieren.
(Die Schlüsselorte Bool, true, false sind aber nicht native, dafür muss
stdbool.h includiert werden. – aber nur in C nicht in C++)
Interessanterweise wird das aber in der C Literatur oft nicht
dargestellt. Wenn es um Datatypes geht wird nur short, int, long…
gelistet.
Und interessant: jede Zuweisung einer Zahl an eine _Bool Variable wird
als Wert 0 oder 1 gespeichert.
bool b = 42;
Wird als Wert 1 gespeichert.
Daher meine Empfehlung: immer den native Datentyp bool nutzen und nicht
durch char/enum/defines was eigenes bauen.
Das Thema ist auf stackoverflow.com schon Tausendmal durchgekaut und es
gibt gute Empfehlungen dazu.
Stefan ⛄ F. schrieb:> und wie es um die> Groß/Klein-Schreibung steht.
MAKROS immer groß.
> man hätte es einfach bei 0/1 belassen sollen
Daran wurde nichts geändert!-O
Wolfgang schrieb:> Rolf M. schrieb:>> Ich denke nicht, dass viele Nicht-C-Programmierer erwarten würden, dass>> so etwas wie (3 == true) auch wieder true ergibt.>> Wenn der Wert einer Variablen x als "true" bewertet wir, erwartet jeder> Nicht-C-Programmierer mit ein bisschen Logikverständnis, dass (x==true)> auch als "true" bewertet wird (Beispiel s.o.).
x wird aber nicht als true bewertet. x ist ein int. true ist ein bool.
Also stehen da erst einmal zwei unterschiedliche Datentypen auf beiden
Seiten des Vergleichs. Also muss einer in den Typ des anderen
konvertiert werden. Hier wird eben der bool nach int konvertiert, weil
in C per Default alles in int gerechnet wird, wo das möglich ist.
> Das sind Grundaussagen der Boolschen Algebra.
In der booleschen Algebra gibt es keine 3. Damit ergibt sich dort auch
nicht die Frage, was rauskommt, wenn man die mit true vergleicht.
Ich hab übrigens gerade mal in Python nachgeschaut. Es ist dort genau
wie in C:
1
$ python3
2
Python 3.8.5 (default, May 27 2021, 13:30:53)
3
[GCC 9.3.0] on linux
4
Type "help", "copyright", "credits" or "license" for more information.
Stefan ⛄ F. schrieb:> Ich benutze stdbool.h und vertraue darauf, dass die Entwickler des C> Compiles (und der Bibliothek) schon wissen, was sie tun.
Und zusätzlich auch noch bei GCC -Wall verwenden. Das quittiert
bool x;
... x == 5 ...
mit einer Warnung.
Stefan ⛄ F. schrieb:> Und Java lässt so einen Vergleich gar nicht zu.
Klar. In C ist das, Rolf schon schrieb, ein Geburtsfehler der Sprache.
Die aus einer Zeit stammt, in der ein Compiler in 64 KB passen sollte,
und in der man sich nur ungern von alten Problemen lösen mag.
Dann irgendwann kam der Wunsch nach Boolean im Sinne von Bits auf, um
Speicher zu sparen. Und heute scheißt man drauf, ob man ein Bit oder
ganze 64 bits für eine ja/nein Aussage belegt, sofern das nicht viele
Millionen mal in einer Anwendung vorkommt.
Stefan ⛄ F. schrieb:> Und heute scheißt man drauf, ob man ein Bit oder> ganze 64 bits für eine ja/nein Aussage belegt
Nicht ganz korrekt. Moderne C Compiler / CPUs nutzen für
bool 1 Byte und nicht 4 Byte. Schon deshalb sollte bool und nicht int
genutzt werden.
BeBe schrieb:> _Bool ist in C ein eigener Datentyp (Native Type). Man braucht dafür> nicht stdbool.h includieren.> (Die Schlüsselorte Bool, true, false sind aber nicht native, dafür muss> stdbool.h includiert werden.
Ein Licht am Ende des Tunnels:
1
N2393 - proposal for C2x
2
In its London 2019 meeting, WG14 has found consensus to elevate
3
false and true to proper keywords. This is only a first step to
4
make these constants first-class language features and to achieve
5
a full compatibility with C++. Therefore we need also to change
6
their type, namely to change them from int to bool, and a
7
deprecation of their use in contexts which are non-logical.
1
N2596 - working draft - December 11, 2020
2
The following documents have been applied to this draft from the
3
October 2019 Meeting:
4
N2393 _Bool Definitions For true and false.
> Daher meine Empfehlung: immer den native Datentyp bool nutzen und nicht> durch char/enum/defines was eigenes bauen.
Bauform B. schrieb:> Ein Licht am Ende des Tunnels:
Danke für die Info. Längst überfällig.
Dauert halt wieder 20 Jahre bis der Großteil der C Programmierer
es verinnerlicht hat...
>> heute scheißt man drauf, ob man ein Bit oder>> ganze 64 bits für eine ja/nein Aussage belegtBeBe schrieb:> Nicht ganz korrekt. Moderne C Compiler / CPUs nutzen für> bool 1 Byte und nicht 4 Byte.
Ich meinte das auch allgemeiner, nicht spezifisch für C. In Java ist ein
boolean 8 Bit, kann aber wegen dem Alignment effektiv bis zu 64 Bit
belegen.
BeBe schrieb:> Moderne C Compiler / CPUs nutzen für> bool 1 Byte und nicht 4 Byte.
Was auf 32-Bit-µCs wie STM32 zu einer Geschwindigkeitseinbuße führt.
Stefan ⛄ F. schrieb:> Ich meinte das auch allgemeiner
Sorry, ich hab geklugscheissert. Es war mir klar, dass Du das weisst. Es
sollte eher als Hinweis an andere dienen. Die Sprache ist zwar alt, aber
wurde auch verbessert (wenn auch zu langsam).
Ich habe oft das Gefühl, dass mehr Leute in der ersten Auflage im K&R
lesen, als in aktuelleren Büchern oder direkt im Standard.
Diesen Blödsinn mit eigenen TRUE und FALSE Makros versuche ich schon
seid Jahren immer wieder weg zu bekommen. Aber lieb gewordene
Angewohnheiten
haben es schwer, selbst wenn es einen verbindlichen Codierstandard gibt,
sickert es immer wieder durch...
Frank M. schrieb:>> bool 1 Byte und nicht 4 Byte.>> Was auf 32-Bit-µCs wie STM32 zu einer Geschwindigkeitseinbuße führt.
Im Register sind reine Bytes blöd. Was im Speicher ein Byte belegt, darf
im Register aber in voller Breite blühen. Und anders als bei Zahlen,
kriegt man im Umgang mit Bools kein Wertebereichsproblem.
Teo D. schrieb:> Du meinst BASIC Programmierer von 1978! Der Rest, hält diesen Ausdruck> für Schwachsinnig.
Du kannst Regeln der Boolsche Algebra als "schwachsinnig" bezeichnen.
Das ändert aber nichts daran, dass die Umsetzung in C scheitert, weil es
den Wert "truly" für eine Variable nicht gibt.
Rolf M. schrieb:> x wird aber nicht als true bewertet
Was macht
Wolfgang schrieb:> Du kannst Regeln der Boolsche Algebra als "schwachsinnig" bezeichnen.> Das ändert aber nichts daran, dass die Umsetzung in C scheitert, weil es> den Wert "truly" für eine Variable nicht gibt.
?
Frank M. schrieb:> Was auf 32-Bit-µCs wie STM32 zu einer Geschwindigkeitseinbuße führt.
Wobei wir wieder beim Thema sind. Wo liegt das Problem?
Moderne CPUs haben viel Speicher und viel Performance.
Ob ich auf Speicher optimier oder auf Performance hängt an der
Applikation.
Ich optimiere, wenn ich bei Performance- oder Speicher-Tests einen
Engpass sehe.
Dabei ist es egal ob bool, int, float, double… Erst der Algorithmus,
dann die Optimierung.
Wolfgang schrieb:> Rolf M. schrieb:>> x wird aber nicht als true bewertet>> Was macht if (x) denn sonst?
Hier wirds sprachlich etwas heikel. Ein if() Statement hat keine
Beziehung zu Bool als Datentyp, damit auch nicht zu "true" als
Sprachelement.
BeBe schrieb:> Ich habe oft das Gefühl, dass mehr Leute in der ersten Auflage im K&R> lesen, als in aktuelleren Büchern oder direkt im Standard.
Erwischt. Liegt wohl daran, dass das Buch wirklich sehr gut ist.
Wolfgang schrieb:> Was machtif (x) denn sonst?
Siehe ISO/IEC 9899, Ch. 6.8.4.1 The ifstatement
if ( expression ) statement
if ( expression ) statement else statement
In both forms, the first substatement is executed if the expression
compares unequal to 0. In the elseform, the second substatement is
executed if the expression compares equal to 0.
Da steht nix von bool.
expressioin wird immer als ein Integer Ergebnis betrachtet und nicht als
bool. Das sollte man nicht vergessen.
Stefan ⛄ F. schrieb:> Erwischt. Liegt wohl daran, dass das Buch wirklich sehr gut ist.
Ahhhhh, hoffentlich wirst Du jetzt nicht im Forum virtuell
zerfleischt... :-)
C ist halt ziemlich hardwarenah - fragt sich nur zu welcher Hardware.
Wenn man das aus AVR Sicht sieht, müsste ein int per default 8bit haben.
Ich denke, dass man beim Design der Sprache damals heftige Kompromisse
machen musste. Sun hat mit Java versucht, all diese Kompromisse
abzuschaffen, aber das Ergebnis ist fast genau so inkonsequent.
(prx) A. K. schrieb:> Ein if() Statement hat keine> Beziehung zu Bool als Datentyp, damit auch nicht zu "true" als> Sprachelement.
Worauf, wenn nicht auf wahr oder falsch, basiert bei if () denn sonst
die Entscheidung?
Das Kind ist einfach in den Brunnen gefallen und C in dieser Hinsicht
verkorkst. Bei der Definition hat man es nicht geschafft, die Auswertung
des Z-Flags im Statusregister von Assembler sauber in die "Hoch"-Sprache
C zu portieren.
Wenn andere Sprachen das Verhalten nachmachen, sehe ich da nur ein
Zugeständnis zur Kompatibilität mit C.
Stefan ⛄ F. schrieb:> Liegt wohl daran, dass das Buch wirklich sehr gut ist.
Als Lehrbuch wars OK. Vor ANSI-C war es aber auch die Sprachreferenz,
und da hatte es Schwächen.
Wolfgang schrieb:> Worauf, wenn nicht auf wahr oder falsch, basiert bei if () denn sonst> die Entscheidung?
Hat BeBe doch aus der Spec zitiert: Auf 0 node nicht 0.
Da wird einfach nur Zero-Flag abgefragt.
Wolfgang schrieb:> Worauf, wenn nicht auf wahr oder falsch, basiert bei if () denn sonst> die Entscheidung?
Ich schrieb ja schon, dass einem hier die doppelte Bedeutung von "true"
einen Streich spielen kann, zusammen mit Englisch/Deutschem
Kauderwelsch. Meint man damit den Zustand der if()-Bedingung, oder den
Wert einer Boolean?
In if(x) hat x nichts mit Booleans zu tun, somit auch nicht mit einem
Sprachelement "true". Indes ist es als Zustand der Bedingung wahr, in
Englisch ausgedrückt "true". Auf diese Art kann man wunderschön
aneinander vorbei reden.
Stefan ⛄ F. schrieb:> Da wird einfach nur Zero-Flag abgefragt.
So es überhaupt eines gibt, und der Test darin landet. Das muss beides
nicht der Fall sein.
Rolf M. schrieb:> Der Entwickler war zugleich für Tests zuständig.
Das ist der größte aller Fehler den man machen kann. Und das weiß ich
als Programmierer ganz genau. Unter MEINEN Bedingungen und Tests läuft
das Prg. immer, wenn ich es raus gebe. Aber andere Leute andere
Denkweisen, ergo neue mögliche Fehler die ich übersehen habe.
Dann kommt das Prg. zurück und ich beseitige die Fehler.
Falk B. schrieb:
> Ich hab TRUE/FALSE so gut wie nie verwendet und immer> nur manuell 0/1 in Variabeln geschrieben
Ja so Speicherverschwender sind ja bekannt. ;) Weshalb die Software auch
immer dicker wird, ohne was wirklich neues zu machen.
Wenn ich programmiere ist True/False klar durch den Compiler definiert.
Also einfach gesagt, der Compiler kann das, und ich setze es ein. Meist
als "Statusschalter".
Was die Abfrage von einen Status angeht einer Hardware die ich am
digitalen Port eines Arduinos o.ä. abfrage, nutze ich NIE True/False
sondern IMMER high/Low. Das löst dann Probleme bevor sie entstehen.
Ob True nun 1 o. -1 o. 0 ist, ist mir völlig egal. Ich habe und werde
NIEMALS Zahlen mit einen Status mischen. Wie oben gesagt : Das löst dann
Probleme bevor sie entstehen.
Entweder ich definiere eine Variable als Integer (einfache Zahl wenn ich
nicht mehr brauche) o. als Boolean (klarer Status).
Und ja ich bin altmodisch. Aber diese Art von Problemen hatte ich
deshalb auch noch NIE. ;)
(prx) A. K. schrieb:> In if(x) hat x nichts mit Booleans zu tun, somit auch nicht mit einem> Sprachelement "true". Indes ist es als Zustand der Bedingung wahr, in> Englisch ausgedrückt "true". Auf diese Art kann man wunderschön> aneinander vorbei reden.
Eben, eine Hochsprache soll eigentlich so klar sein, dass ein
"aneinander vorbei reden" vermieden wird. Worauf, wenn nicht auf eine
wahr/falsch willst du denn eine binäre Entscheidung, wie sie hinter if
() steht, sonst aufbauen.
Mein Beispiel von oben anders fomuliert:
Wenn ein Werte x als "ungleich 0" bewertet wird, sollte auch (x ==
nicht-0), i.e. (x = !false) als "ungleich 0" bewertet werden - tut es in
C aber nicht (und alles ganz ohne "true").
Wolfgang schrieb:> (prx) A. K. schrieb:>> Ein if() Statement hat keine>> Beziehung zu Bool als Datentyp, damit auch nicht zu "true" als>> Sprachelement.>> Worauf, wenn nicht auf wahr oder falsch, basiert bei if () denn sonst> die Entscheidung?
Sorry
Textverständnis = Unzureichend! -> Lesen und denken, noch mal lesen,
noch mehr denken...
Ich weiß, ich weiß. Ich krieg das auch 'nich immer' hin. Aber ich bemüh
mich. :DDD
Wolfgang schrieb:> Wenn ein Werte x als "ungleich 0" bewertet wird, sollte auch (x ==> nicht-0), i.e. (x = !false) als "ungleich 0" bewertet werden - tut es in> C aber nicht (und alles ganz ohne "true").
Wolfgang, Du drehst Dich im Kreis: Du wirfst immer noch TRUE als
boolscher Zustand und die Auswertung für if etc. durcheinander, ohne
dich irgendwo irgendwann festzulegen. Du kannst bei Deinem Compiler die
Warnungen einschalten und eine Zuweisung oder einen Vergleich von bool
und Integer zu verhindern. Du kannst es auch sein lassen, wenn Du es
trennst (integer-Ausdrücke in Abfragen, 0/1 in Bool). Du kannst auch
jeden Ausdruck mit !!boolearisieren, ganz wie Du magst. Du kannst nur
nicht immer ein System aus dem anderen Blickwinkel sehen.
Beispiel hier: Ja, Du kannst Dich beschweren, dass (X == TRUE)
eigentlich ein X==!0 ist. Aber genau dafür gibt es das X!=0. Das ist nun
mal so bei jeder Menge mit mehr als 2 Elementen.
Und ja, Du kannst natürlich fordern, dass if-Abfragen einen boolschen
Ausdruck benötigen. Aber ich glaube, da gibt es mehrere Punkte, die man
mit wenigen Seiten und vielen zusätzlichen Warnungen für den Anfänger
restriktiver gestalten könnte und für alle anderen komplizierter. Und
ja, man kann darüber schreiten, ob "if(mode)" oder "if(error)" zur
Lesbarkeit beitragen, und da billige ich Dir gerne eine Abweichende
Meinung zu. Dass Deine aber allein richtig ist, sehe ich nicht ein.
BeBe schrieb:> Diesen Blödsinn mit eigenen TRUE und FALSE Makros versuche ich schon> seid Jahren immer wieder weg zu bekommen.
Genauso wie die nervige Angewohnheit, dass immer noch fast jeder seine
eigene Alternative zu den stdint-Typedefs wie uint32_t u.s.w. bastelt.
BeBe schrieb:> Frank M. schrieb:>> Was auf 32-Bit-µCs wie STM32 zu einer Geschwindigkeitseinbuße führt.> Wobei wir wieder beim Thema sind. Wo liegt das Problem?> Moderne CPUs haben viel Speicher und viel Performance.> Ob ich auf Speicher optimier oder auf Performance hängt an der> Applikation.
Nur kann man die Größe von bool oft nicht von der Applikation abhängig
machen, da sie ein Teil des ABI ist. Das ist wie beim avr-gcc mit seinem
-mint8, um die Größe von int auf (nicht standardkonforme) 8 Bit zu
ändern. Kann man zwar machen, aber dann kannst du die avr-libc und alle
anderen Bibliotheken in Binärform nicht mehr nutzen, weil dazu nicht
kompatibel.
Stefan ⛄ F. schrieb:> C ist halt ziemlich hardwarenah - fragt sich nur zu welcher Hardware.
C versucht halt, den Spagat zu machen, einerseits möglichst hardwarenah
zu sein, andererseits auf möglichst viel verschiedener Hardware sinnvoll
umsetzbar zu sein. Deshalb lässt es viele Dinge offen, damit sie an die
jeweilige Hardware angepasst werden können. ich würde sagen, das ist
eines der wichtigsten Konzepte hinter der Sprache und auch einer der
Gründe, weshalb man es auch heute noch vom kleinsten 8-Bitter mit <1k
RAM über irgendwelche exotischen DSPs bis zum Supercomputer überall
vorfindet. Ganz falsch kann das also nicht sein.
Schlaumaier schrieb:> Rolf M. schrieb:>> Der Entwickler war zugleich für Tests zuständig.>> Das ist der größte aller Fehler den man machen kann. Und das weiß ich> als Programmierer ganz genau. Unter MEINEN Bedingungen und Tests läuft> das Prg. immer, wenn ich es raus gebe. Aber andere Leute andere> Denkweisen, ergo neue mögliche Fehler die ich übersehen habe.
Vor allem kennst du ja deinen eigenen Code und baust deshalb unbewusst
genau die Tests, von denen du eigentlich schon weißt, dass sie
wahrscheinlich erfolgreich sein werden. Denn beim Testen wirst du auf
genau die Dinge achten, auf die du beim Programmieren auch schon
geachtet hast.
Dann setzt du jemand anders dran, und innerhalb von 5 Minuten fällt dein
Programm komplett auseinander, weil der was macht, was dir gar nicht in
den Sinn gekommen wäre. Ich kenne so Leute, die da perfekt drin sind.
Das sind die geborenen Tester. :-)
Wolfgang schrieb:> Eben, eine Hochsprache soll eigentlich so klar sein, dass ein> "aneinander vorbei reden" vermieden wird. Worauf, wenn nicht auf eine> wahr/falsch willst du denn eine binäre Entscheidung, wie sie hinter if> () steht, sonst aufbauen.
Das ist wie schon gesagt ein Problem, das daraus entsteht, dass C
ursprünglich kein bool kannte und das daher alles mit int ausgedrückt
hat.
> Mein Beispiel von oben anders fomuliert:> Wenn ein Werte x als "ungleich 0" bewertet wird, sollte auch (x ==> nicht-0), i.e. (x = !false) als "ungleich 0" bewertet werden - tut es in> C aber nicht (und alles ganz ohne "true").
Und da sind wir wieder an der Stelle. Wie drückst du "nicht-0" als int
aus? Du müsstest dann also so etwas haben:
1
inta=5;
2
intb=everything_but_zero;
3
if(a==b)
4
printf("a is not 0\n");
Aber da du ja immer auf der Algebra rumreitest: Würdest du hier
erwarten, dass der Vergleich a == b nur für a = 0 falsch ergibt und für
jeden beliebigen anderen Wert true?
A. S. schrieb:> Beispiel hier: Ja, Du kannst Dich beschweren, dass (X == TRUE)> eigentlich ein X==!0 ist. Aber genau dafür gibt es das X!=0. Das ist nun> mal so bei jeder Menge mit mehr als 2 Elementen.
Ja genau das ist der Punkt. X == !0 ist eben nicht das selbe wie X != 0,
da !0 nicht die Menge aller Zahlen außer 0 ist.
Rolf M. schrieb:> Und da sind wir wieder an der Stelle. Wie drückst du "nicht-0" als int> aus?
Ganz einfach als 1.
Wenn man kein Boolean hat, muss man sich zu helfen wissen. Ergo schreibt
man in den Code oben als Kommentar : "0 = false / 1 = true"
Nun muss man nur drauf aufpassen das die Variable kein andere Wert
bekommt und alles ist gut. Und seine Variablen sollte man eh immer im
Kopf habe, mit ihren möglichen Werten an JEDER Stelle des Programms.
Und da es "Halb schwanger" nicht gibt, hat die Variable entweder 0 oder
1.
Das ganze True/False wurde nur als 2 Gründen erfunden.
1.) Man braucht weniger Speicherplatz (max. 1 Byte einige Sprachen sogar
weniger). Es gab man eine Zeit wo der sehr knapp war.
Ich habe damals 8 True/False Werte in EINE Variable mit 1 Bytes
Speicherplatz gequetscht. So Probleme hat man halt wenn der
Variablen-Speicher begrenzt ist. Etwas was ich nun (in Ähnlicher Form)
wieder mache, bei der Arduino-Programmierung.
2.) Es ist einfacher zu lesen und sich zu merken als das 0 + 1 Zeug.
Schlaumaier schrieb:> Ich habe damals 8 True/False Werte in EINE Variable mit 1 Bytes> Speicherplatz gequetscht.
Dass geht aber auch, wenn Booleans eigenständige Datentypen sind, keine
Integers. Und nicht erst seit heute: "packed array of boolean" in
PASCAL.
Rolf M. schrieb:> Genauso wie die nervige Angewohnheit, dass immer noch fast jeder seine> eigene Alternative zu den stdint-Typedefs wie uint32_t u.s.w. bastelt.
Ich gehöre leider zu denen. Meist wegen short/int/long in printf, bei
Code der auf 16-bit embedded und PC läuft. Oder wo die Größe von bool
wichtig ist. Auch wchar war bei manchen Compilern schwierig.
(prx) A. K. schrieb:> "packed array of boolean"
hihi. nö. Ich habe einfach ein String mit 1 Bytes deklariert und dann
den Inhalt bit-mässig aufgelöst.
Wie gesagt, sehr ähnlich wie bei den Arduinos heutzutage.
Allerdings muss ich mich Outen. Ich hielt damals "PASCAL" für ein
Französischen Basic. ;) Und hab ihm keine Zukunft gegeben.
Eine Meinung die sich als Richtig erweisen hat. Das "normale" Basic hat
sich bisher, zugegeben in Wandlungen bis heute durchgesetzt. Selbst für
Arduinos ;)
Aber es gab damals auch "Taschenrechner mit Basic" und da war der
Speicher ekelhaft klein. Da musste man tricksen ohne Ende. Und ich habe
meine ganzen Buchführungsberechnungen da rein gequetscht, in die ca. 3.5
KB (inkl. Variablenspeicher).
Schlaumaier schrieb:> Ich habe einfach ein String mit 1 Bytes deklariert und dann> den Inhalt bit-mässig aufgelöst.
Klar. Man kann auch Assembler verwenden, das geht auch und c-hater ist
dann glücklich.
Wenn dir PASCAL nicht zusagt, betrachte BIT in PL/1 (entstammt den
60ern). Ist das dortige Boolean und IF erwartet ebendies als Wert - die
Kurzform von generellen Bitstrings wie BIT(8) oder BIT(1200).
Konstanten wie '10101010'B oder 'AA'B4. Bitweise Verarbeitung,
Verkettung, ... sind aber natürlich keine Integers.
Der Unterschied zu C: Ein PL/I Compiler ist viel komplexer als ein C
Compiler der damaligen Ära. Erste Implementierungen benötigten auf
damaligen Mainframes eine 2stellige Anzahl Passes. Aber trotzdem gelang
es später, einen sinnvollen Subset auf eine 8080 CPU zu kriegen.
Aber eigentlich geht es heute nicht (mehr) darum, die Sprache minimalst
zu halten, sondern sinnvolle Trennungen auch durchzuziehen. In C ist das
nicht mehr möglich.
A. S. schrieb:> Meist wegen short/int/long in printf, bei Code der auf 16-bit embedded und> PC läuft.
Den Zusammenhang verstehe ich jetzt nicht. Einen uint32_t kann man per
1
printf("Der Wert ist %"PRIu32,wert);
ausgeben.
Kleine Randontiz: Oft sieht man das ohne das Leerzeichen zwischen dem
Anführungszeichen und dem PRIu32. Das bricht aber mit der Kompatibilität
zu C++, weshalb ich da immer ein Leerzeichen setze.
(prx) A. K. schrieb:> Aber eigentlich geht es heute nicht (mehr) darum, die Sprache minimalst> zu halten, sondern sinnvolle Trennungen auch durchzuziehen.
Völlig richtig.
Deshalb deklariere ich die Variable als BOOLEAN. Das reicht für eine
Sinnvolle Trennung. Sobald die nämlich ein anderen Zustand als
True/False hat, haut die IDE (oder spätestens der Compiler) mir die um
die Ohren = fehlerhafte Deklarierung o.ä. nette Sprüche.
Womit die Diskussion mit den 0 // 1 // -1 völlig Sinnfrei ist, da keiner
mehr Sprachen auf alten Stand programmieren muss. Und ich denke da True
/ False inzwischen auch in C (+) angekommen ist.
Rolf M. schrieb:> Genauso wie die nervige Angewohnheit, dass immer noch fast jeder seine> eigene Alternative zu den stdint-Typedefs wie uint32_t u.s.w. bastelt.
Fast jeder? Ich kenne nur zwei: Arduino und W.S.
Rolf M. schrieb:> Ich kenne so Leute, die da perfekt drin sind.> Das sind die geborenen Tester. :-)
Manchmal nerven mich die Kollegen mit ihren bekloppen Einfällen, aber
andererseits soll das ja auch so sein. Nur so wird das System stabil.
Da hat jemand einen Händler A angelegt, und der hat Unterhändler A1, A2,
A3, usw. Danach hat er den "parent" von A auf A3 geändert. Wenn man
anschließend die Händler mit Hierarchie anzeigt, hängt sich die
Anwendung in einer Endlosschleife auf, bis ein Stack Overflow
stattfindet.
An sowas denkt man bei der Entwicklung nicht.
Die Diskussion, ob man mit #define irgendwelche Konstanten definiert,
ist sowas von Neunziger...
Daß dir das so verschwommen vorkommt, könnte am zeitlichen Abstand
liegen zu der Zeit, als man das mal machte.
Am Alkohol bestimmt nicht. Die Diskussion war heute morgen schon
nüchtern ziemlich daneben.
(prx) A. K. schrieb:> Man kann auch Assembler verwenden, das geht auch und c-hater ist> dann glücklich.
Genau. Wer Assembler wirklich kann, der weiß folgendes: "Datentypen"
sind ziemlicher Schwachsinn, zumindest wenn der Verbleib in ihrem
Wertebereich nicht kontrolliert oder durch den Code selber sicher
gestellt wird.
Und genau das ist die Situation bei C. Und genau deswegen ist C Dreck.
Kaum besser als den Kram direkt in Assembler hinzuschreiben.
C-Datentypen sind huppse, (fast) vollkommen nutzloser Syntax-Ballast.
Man ist in C genauso wie in Assembler selber dafür verantwortlich, dass
Ergebnisse von Berechnungen im Gültigkeitsbereich des gewählten
"Datentypen" bleiben. Es ist nur in Assembler deutlich einfacher, das
auch zu kontrollieren, ohne den Code allzusehr aufzublasen...
Weil das so ist, wie es ist, hat uns C diese unzähligen
Sicherheitslücken gebracht, die auf die eine oder andere Art auf
numerische Überläufe zurückzuführen sind...
Unbrauchbarer Vollrotz, der trotzdem zum Quasi-Standard geworden ist.
Wie VHS. Aber: VHS ist heute tot. Ich hoffe, dass auch C irgendwann
stirbt...
Nicht, dass Rust in dieser Beziehung irgendwie besser wäre. Das
adressiert mit beachtlichem Aufwand (und mindestens genauso beschissener
Syntax) primär ein anderes C-Problem, die de facto nicht existente
Speicherverwaltung. Aber auch hier ist Assembler kaum schlechter als
C...
Gibt es eigentlich keine Arbeit für dich, oder warum müllst du jeden
Thread mit deinem
Assembler-ist-so-toll-und-alles-andere-ist-Müll-Getrolle voll?
Vielleicht bist du mit Assembler so effizient im Programmieren, daß du
ganz viel Zeit hast und dann Langeweile bekommst...
Wahrscheinlich schreibst du deine ganzen konstruktiven Beiträge unter
einem anderen Namen.
Klaus W. schrieb:> Gibt es eigentlich keine Arbeit für dich, oder warum müllst du jeden> Thread mit deinem> Assembler-ist-so-toll-und-alles-andere-ist-Müll-Getrolle voll?> ...> Wahrscheinlich schreibst du deine ganzen konstruktiven Beiträge unter> einem anderen Namen.
Interessanterweise kommen in diesem Forum zielführende Antworten zu
Assemblerfragen nicht etwa von den aggressiven Hochsprachengegnern,
sondern praktisch immer von Leuten, die sonst auch zu C-Fragen
kompetente Beiträge schreiben.
c-hater schrieb:> Und genau deswegen ist C Dreck.
Dafür ist C aber portabler als Assembler. Bei einem CPU-Familienwechsel
muss der Assembler-Programmierer das Programm komplett neu schreiben.
Das ist weggeworfene Lebenszeit.
Der C-Programmierer braucht lediglich die hardwarenahen Module neu zu
implementieren und kann sogar den Code für beide oder noch mehr
CPU-Familien weiter warten, da der Großteil des Codes ein- und derselbe
ist.
Tut mir leid, da kannst Du auf C schimpfen wie Du willst. Die
Portabilität ist ein absolutes K.O.-Kriterium für mich. Mit Assembler
unerreichbar.
Um das Ganze noch verworrener zu machen, wird bei Returnwerten oft mit 0
die Fehlerfreiheit gekennzeichnet (0 = success). Ein Wert != 0 ist
dagegen false, d.h. der Fehlerkode, was schief gelaufen ist.
In Batch-Dateien ist das der Errorlevel, den man auswerten kann.
Peter D. schrieb:> Um das Ganze noch verworrener zu machen, wird bei Returnwerten oft mit 0> die Fehlerfreiheit gekennzeichnet (0 = success). Ein Wert != 0 ist> dagegen false,
Falsche Sichtweise. Das ist nicht boolean, also wahr/falsch, sondern
einfach nur ein Fehler-Code. Das auf !0 zu prüfen, ist nur praktisch und
nur zufällig boolean ähnlich.
Peter D. schrieb:> Um das Ganze noch verworrener zu machen, wird bei Returnwerten oft mit 0> die Fehlerfreiheit gekennzeichnet (0 = success).
Das kommt aus der Unix-Welt, dort ist 0 (manchmal auch >=0 bei z.B.
read/write) oft Success, negative Werte zeigen Fehler an. Da die meisten
der (Posix-)Funktionen mehr als nur Schwarz/Weiß-Werte zurückliefern,
ist hier TRUE/FALSE auch nicht zielführend.
Peter D. schrieb:> Ein Wert != 0 ist dagegen false, d.h. der Fehlerkode, was schief> gelaufen ist
Das ist ja meist gut, da es viele Fehler gibt und nur ein gut.
Verwirrend ist es jedoch bei z.b. strcmp, wo man intuitiv denkt,
Gleichheit müsste im If "true" ergeben.
Teo schrieb:> Peter D. schrieb:>> Um das Ganze noch verworrener zu machen, wird bei>> Returnwerten oft mit 0 die Fehlerfreiheit>> gekennzeichnet (0 = success). Ein Wert != 0 ist>> dagegen false,>> Falsche Sichtweise.
Nein.
Die Konvention, die Peter genannt hat, ist der Grund
dafür, dass ich mir die Wahrheitswerte in C nicht
merken kann.
Frank M. schrieb:> Peter D. schrieb:>> Um das Ganze noch verworrener zu machen, wird bei>> Returnwerten oft mit 0 die Fehlerfreiheit>> gekennzeichnet (0 = success).>> Das kommt aus der Unix-Welt,
Ach.
Im krassen Gegensatz dazu kommt "C"... woher nochmal?
> Da die meisten der (Posix-)Funktionen mehr als nur> Schwarz/Weiß-Werte zurückliefern, ist hier TRUE/FALSE> auch nicht zielführend.
Das gesamte "Typsystem" von C ist nicht zielführend.
Egon D. schrieb:>> Das kommt aus der Unix-Welt,>> Ach.> Im krassen Gegensatz dazu kommt "C"... woher nochmal?
Und? Da waren damals Praktiker am Werk, keine Prinzipienreiter. Für den
Exit-Status von Prozessen oder APIs wars mit 0=success sinnvoller.
Bei Microsoft kann man dafür ein ziemliches Kuddelmuddel finden. Mal
liefert der Return-Status sowas wie in Unix/Linux ab, mal 1=success und
Fehlerstatus extra.
> Das gesamte "Typsystem" von C ist nicht zielführend.
Man sollte eine neue Programmiersprache definieren, die alle Probleme
löst, und die gesamte Industrie mit Stichtag 1.4.2025 dazu verpflichten,
Programme ausschliesslich darin zu entwickeln. Ohne diesen Zwang kommt
ja doch bloss https://xkcd.com/927/ raus. ;-)
(prx) A. K. schrieb:> Dann nimmt halt die C-Shell statt Bourne. ;-)
Das führt dann dazu, dass ich die Rückgabewerte
der Shell AUCH nicht mehr korrekt interpretieren
kann?
Egon D. schrieb:> Das führt dann dazu, dass ich die Rückgabewerte> der Shell AUCH nicht mehr korrekt interpretieren> kann?
Yep, dann bist du auch innerhalb der Shell verwirrt, nicht nur
zwischen Shell und C-Programm. ;-)
(prx) A. K. schrieb:> Man sollte eine neue Programmiersprache definieren, die alle Probleme> löst
Dazu ist nicht genug Zeit, eher ist die Sonne erloschen.
Programmiersprachen werden immer Kompromisse bleiben mit Undefined
behavior usw.
Peter D. schrieb:> Dazu ist nicht genug Zeit, eher ist die Sonne erloschen.> Programmiersprachen werden immer Kompromisse bleiben mit Undefined> behavior usw.
Natürlich. Das ganze Theater um nicht perfektes C ist ziemlich sinnarm,
weil das als nutzbares Werkzeug einfach da ist und nicht per Federstrich
oder Antipathie wegdefiniert werden kann.
Wenn man allmählich bessere Sprachen einfliessen lässt, wie etwa Rust
beim Linux Kernel, halte ich das freilich durchaus für sinnvoll. Aber
auch das wird nicht übers Knie gebrochen.
Peter D. schrieb:> (prx) A. K. schrieb:>> Man sollte eine neue Programmiersprache definieren, die alle Probleme>> löst>> Dazu ist nicht genug Zeit, eher ist die Sonne erloschen.> Programmiersprachen werden immer Kompromisse bleiben mit Undefined> behavior usw.
Das wurde doch schon erfunden!
Nennt sich KI. :D
Jetzt noch meine Meinung zu true / false in C.
Sachen wie BOOL, TRUE und FALSE kommen mir nicht in den code, heute gibt
es stdbool.h, mit bool, true und false. Zeugs wie TRUE und FALSE nutze
ich höchstens, wenn es ein altes Projekt von jemand anderem ist, wo es
schon verwendet wird.
Ich sehe auch nicht, was an der Sache so kompliziert oder problematisch
sein soll. true -> 1, false -> 0, und (bool)42 -> 1. That's it. Sachen
wie while, if, und boolsche Operatoren, &&, ||, usw. konvertieren halt
quasi nach bool. Nicht boolsche Operatoren (+ - * / == != ^ & % usw.),
machen das halt nicht (weil sind ja auch kleine boolschen Operatoren).
Ist halt so, und ist auch gut so.
Das einzige was mich stört, ist, dass es kein boolsches gleich, und kein
boolsches xor gibt. Da muss man extra !!(a) == !!(b) oder !!(a) == !!(b)
schreiben. Das ist aber auch nicht das Ende der Welt.
(Und ASM ist ja wohl hier noch schlimmer. Da muss man immer nachsehen,
welche Instruktionen setzen oder clearen welche flags, welche branching
Instruktion nutz ich da jetzt für, etc. Von der unportierbarkeit mal
ganz zu schweigen, sowie Platformspezifischen Unzulänglichkeiten, wo
selbst simpelste Dinge wie z.B. rechnen mit grösseren Zahlen oder
Floats, etc. zur Mamut Aufgabe werden kann, wenn da mal keine
Instruktion für da ist, und man das jedes mal wieder selbst machen muss.
Das ist sicher auch viel sicherer und weniger fehleranfällig...)
(prx) A. K. schrieb:> Bei Microsoft kann man dafür ein ziemliches Kuddelmuddel finden. Mal> liefert der Return-Status sowas wie in Unix/Linux ab, mal 1=success und> Fehlerstatus extra.
Eben, das "Kuddelmuddel" haben erst später andere in C produziert. Die
UNIX-/Linux-/Posix-Welt ist da eher in sich homogen und geschlossen.
A. S. schrieb:> Verwirrend ist es jedoch bei z.b. strcmp, wo man intuitiv denkt,> Gleichheit müsste im If "true" ergeben.
strcmp() liefert im Nicht-Gleichheitsfall negative oder positive Werte
zurück - und das mit einem hehren Ziel: Es als Callback-Funktion für
qsort() nutzen zu können. Von daher hat das alles durchaus einen Sinn.
Und vor allem heißt strcmp() ja auch nicht streq(), weil es eben
vergleicht.
Dementsprechend ist die Rückgabe ja auch nicht "ja, sind gleich" oder
"nein, sind ungleich", sondern das Ergebnis ist "erster ist kleiner als
der zweite" oder "beide sind gleich" oder "erster ist größer als der
zweite".
Was hat ein Rückgabewert mit drei Möglichkeiten jetzt mit true und false
zu tun?
Vielleicht sollten wir C wirklich in die Tonne treten und eine neue
Sprache ausdenken.
Da gäbe es dann für bool nicht nur wahr und falsch, sondern noch ein
vielleicht, ein naja, ein muss nochmal drüber nachdenken und ein was
sagt denn Google dazu.
Die Sprache könnte dann heißen Schaumermaldannwirdsschoowern.
🐧 DPA 🐧 schrieb:> Und ASM ist ja wohl hier noch schlimmer. [...]
Das ist kein sinnvoller Vergleich.
Beim Assembler ist von vornherein klar, dass man kein
Typsystem hat.
Dass das C-Typsystem zu kaum mehr taugt als Speicher-
platz für die Variablen zu reservieren, das muss der
naive Pascal-Eleve erst schmerzlich lernen...
Achso, die drei Rückgabewerte für kleiner, gleich und größer gibt es in
C++ übrigens mittlerweile im Operator <=>
Nur das vielleicht fehlt noch, kommt dann mit C++ 23.
Klaus W. schrieb:> Achso, die drei Rückgabewerte für kleiner, gleich und größer gibt es in> C++ übrigens mittlerweile im Operator
strcmp() liefert mehr als nur 3 Rückgabewerte zurück - und das aus gutem
Grund ;-)
Hallo,
Klaus W. schrieb:> Vielleicht sollten wir C wirklich in die Tonne treten und eine neue> Sprache ausdenken.> Da gäbe es dann für bool nicht nur wahr und falsch, sondern noch ein> vielleicht, ein naja, ein muss nochmal drüber nachdenken und ein was> sagt denn Google dazu.> Die Sprache könnte dann heißen Schaumermaldannwirdsschoowern.
:-))))
Und der Schalter zum deaktivieren aller Warnungen heißt dann "Et hätt
noch immer jot jejange".
rhf
(prx) A. K. schrieb:> Das ganze Theater um nicht perfektes C ist ziemlich> sinnarm, weil das als nutzbares Werkzeug einfach da> ist und nicht per Federstrich oder Antipathie> wegdefiniert werden kann.
Doch, könnte man: Wenn C als Zwischensprache für Compiler
genutzt würde -- wie das ja mit dem Assembler auch schon
funktioniert.
Dann könnte ich bei Bedarf jedes beliebige Target mit
FreePascal programmieren, auch wenn FP gar keine explizite
Unterstützung für dieses Target enthält -- sofern ich einen
C-Compiler habe natürlich.
Wer das nicht will, kann direkt C verwenden, oder er steigt
noch eine Stufe zum Assembler hinab.
In Assembler hat man natürlich Typen.
Halt je nach System mal die einen, mal die anderen.
Int und unsigned in ein paar Längen, manchmal sogar diverse
Gleikommazahlen, und Adressen.
Nur dass der Typ nicht dransteht, sondern sich aus den Operationen
ergibt.
Egon D. schrieb:> Dass das C-Typsystem zu kaum mehr taugt als Speicher-> platz für die Variablen zu reservieren,
So krass würde ich es nicht formulieren.
Aber C ist halt eine sehr alte Sprache, die in ihren Ursprüngen genau
einen Integer-Typen kannte und den man nicht einmal explizit
hinschreiben musste. An Strukturen oder sowas gar nicht mal zu denken.
Wir sollten uns einfach von dieser alten Sprache trennen.
Alte Zöpfe abschneiden.
Frank M. schrieb:> Klaus W. schrieb:>> Achso, die drei Rückgabewerte für kleiner, gleich und größer gibt es in>> C++ übrigens mittlerweile im Operator>> strcmp() liefert mehr als nur 3 Rückgabewerte zurück - und das aus gutem> Grund ;-)
Jein ...
strcmp() liefert einen von vielen möglichen Werten zurück, ja.
Aber den Aufrufer geht der Wert nichts an, sondern nur ob er kleiner als
0 ist oder gleich oder größer.
Damit effektiv nur 3 Möglichkeiten.
Klaus W. schrieb:> Nur dass der Typ nicht dransteht, sondern sich aus den Operationen> ergibt.
Sehr eigenwillige Interpretation des Begriffs "Typ".
Es ist doch eben die Eigenschaft, die ein Hochsprachentypensystem vom
Asm abgrenzt, dass die Typeigenschaften eben nicht durch jede Operation
selbst festgelegt werden, sondern zentral vom Typ.
Ja, einige Sprachen machen das besser und andere schlechter.
MaWin schrieb:> Wir sollten uns einfach von dieser alten Sprache trennen.> Alte Zöpfe abschneiden.
Da bräuchte man erstmal eine brauchbare Alternative. Dinge wie Rust, die
ein eigenes Paketmanagemant & Buildsystem haben, und Compilationsunits
nicht getrennt betrachten / keine sauberen separaten Interfaces für die
jeweiligen haben, sind das definitiv nicht.
🐧 DPA 🐧 schrieb:> Dinge wie Rust, die ein eigenes Paketmanagemant & Buildsystem haben,
Dann nutze es halt nicht.
> und Compilationsunits> nicht getrennt betrachten / keine sauberen separaten Interfaces für die> jeweiligen haben
Wo hast du den Unsinn denn her?
Schonmal was von Crates gehört?
MaWin schrieb:>> und Compilationsunits>> nicht getrennt betrachten / keine sauberen separaten Interfaces für die>> jeweiligen haben>> Wo hast du den Unsinn denn her?> Schonmal was von Crates gehört?
Ja. Diese ist kein sauberes separates Interface. Saubere Interfaces
definiert man erst klar, implementiert es dann, und erweitert es später
eventuell etwas. Bei Crates, und Rust im Allgemeinen, ist das
normalerweise umgekehrt, man implementiert es, und Exportiert dann
Zeugs. Und beim Kompilieren muss der Compiler dann weiterhin alle
relevanten Sourcen parsen, um sein typ check zeug machen zu können, also
auch nichts mit Separat.
Wenn ich es nicht mit vertretbarem aufwand mit einem simplen Makefile
bauen kann, in vertretbarere Zeit, und ich die einzelnen Teile nicht
sauber separat zu Object Files kompilieren & linken kann, dann finde
ich das unbrauchbar.
🐧 DPA 🐧 schrieb:> Wenn ich es nicht mit vertretbarem aufwand mit einem simplen Makefile> bauen kann,
Warum geht das nicht?
> in vertretbarere Zeit, und ich die einzelnen Teile nicht> sauber separat zu Object Files kompilieren & linken kann, dann finde> ich das unbrauchbar.
Warum?
MaWin schrieb:> mit vertretbarem aufwand
Das entscheidende Stichwort ist "mit vertretbarem aufwand". So ziemlich
alles, auch die standard library von Rust, ist in crates. Also entweder
verzichtet man auf die (dann muss man nur noch herausfinden, wo die
runtime library ist), oder man nutzt sie, und muss dann das zeug manuell
linken, und beides ist, zumindest für mich, viel zu aufwendig, nur um
rust zu verwenden. Wenn man rustc statt ld zum linken nimmt, ist es
einfacher, aber das ist einfach falsch, ein compiler interface zum
linken zu missbrauchen, da ich keine Rust Projekte machen will, sondern
höchstens Projekte mit Rust.
Und dann besteht das Problem, mit den nicht vorhandenen sauber
getrennten Interfaces immer noch.
🐧 DPA 🐧 schrieb:> Das entscheidende Stichwort ist "mit vertretbarem aufwand".
Zum Glück haben die Rust-Entwickler das Problem für dich gelöst.
Es nennt sich Cargo.
> Und dann besteht das Problem, mit den nicht vorhandenen sauber> getrennten Interfaces immer noch.
Das ist doch an den Haaren herbeigezogen.
Rust interfaces sind sehr sauber getrennt. Deutlich sauberer und
getrennter, als C/C++ Interfaces jemals sein können.
🐧 DPA 🐧 schrieb:> Und dann besteht das Problem, mit den nicht vorhandenen sauber> getrennten Interfaces immer noch.
Ausserdem habe Ich habe kein Interface, wogegen ich das Crate auf
Kompatibilität prüfen könnte, oder das ich woanders nochmal als
Grundlage zur Implementation eines Ersatzes nutzen könnte, oder wogegen
ich Kompilieren könnte, ohne eine konkrete Implementierung zu haben (die
ich erst beim linken brauche.). In C hab ich das, die Header Files.
MaWin schrieb:> Rust interfaces sind sehr sauber getrennt. Deutlich sauberer und> getrennter, als C/C++ Interfaces jemals sein können.
Dan zeig mir mal, wo man sauber getrennt die Interfaces definiert, so
das ein Crate das dann implementieren kann. Und das das so üblich ist.
🐧 DPA 🐧 schrieb:> Ausserdem habe Ich habe kein Interface, wogegen ich das Crate auf> Kompatibilität prüfen könnte, oder das ich woanders nochmal als> Grundlage zur Implementation eines Ersatzes nutzen könnte, oder wogegen> ich Kompilieren könnte, ohne eine konkrete Implementierung zu haben (die> ich erst beim linken brauche.). In C hab ich das, die Header Files.
Das nennt sich Traits in Rust und ist deutlich mächtiger als
C-Deklarationen.
🐧 DPA 🐧 schrieb:> Dan zeig mir mal, wo man sauber getrennt die Interfaces definiert, so> das ein Crate das dann implementieren kann. Und das das so üblich ist.
Ich wüsste gar nicht, wie man es unsauber macht.
Rust zwingt mich, im Gegensatz zu C dazu, die Interfaces explizit zu
deklarieren und freizugeben (pub).
MaWin schrieb:> 🐧 DPA 🐧 schrieb:>> Das entscheidende Stichwort ist "mit vertretbarem aufwand".>> Zum Glück haben die Rust-Entwickler das Problem für dich gelöst.> Es nennt sich Cargo.
Cargo ist nicht die Lösung, sondern teil des Problems. Ich will keine
Rust Projekte machen, ich mache Projekte, mit Make, die eventuell Rust
beinhalten können. Oder eben nicht, weil zu aufwendig, das sauber zu
lösen (also nicht primär als Rust Projekt oder ohne Make).
MaWin schrieb:> 🐧 DPA 🐧 schrieb:>> Dan zeig mir mal, wo man sauber getrennt die Interfaces definiert, so>> das ein Crate das dann implementieren kann. Und das das so üblich ist.>> Ich wüsste gar nicht, wie man es unsauber macht.> Rust zwingt mich, im Gegensatz zu C dazu, die Interfaces explizit zu> deklarieren und freizugeben (pub).
Freigeben, ja. Deklarieren, nein. Bei Rust ist der Code sowohl das
Interface, als auch die Implementation. Es gibt keine Trennung. Das ist
nicht sauber.
🐧 DPA 🐧 schrieb:> Ich will keine Rust Projekte machen
Ja dann sag das doch direkt, dass du Rust gar nicht verwenden willst und
nur uninformiert stänkern willst.
MaWin schrieb:> 🐧 DPA 🐧 schrieb:>> Bei Rust ist der Code sowohl das>> Interface, als auch die Implementation. Es gibt keine Trennung.>> Das ist halt falsch.> Traits.
Auch Traits sind nicht interfaces in dem Sinne. Ich kann keine Traits
nutzen, ohne im vornherein eine Implementierung zu haben. Siehe in der
Dokumentation, man braucht die Implementation im Vornherein, beim
Kompilieren: https://doc.rust-lang.org/rust-by-example/trait.html
🐧 DPA 🐧 schrieb:> Auch Traits sind nicht interfaces in dem Sinne. Ich kann keine Traits> nutzen, ohne im vornherein eine Implementierung zu haben.
Das ist einfach nur falsch.
MaWin schrieb:> 🐧 DPA 🐧 schrieb:>> Auch Traits sind nicht interfaces in dem Sinne. Ich kann keine Traits>> nutzen, ohne im vornherein eine Implementierung zu haben.>> Das ist einfach nur falsch.
Na dann zeig mal ein Beispiel, dass das belegt. Ein trait ohne konkrete
Implementierung, der Aufruf einer Funktion davon. Als separates Projekt,
die Implementierung des Trait. Und dann kompiliere ersteres ohne
Letzteres, und linke letzteres nachher nur dazu mit ld. Ich behaupte,
das geht so nicht.
Aber selbst wenn das machbar wäre, (irgend einen Mechanismus wird es ja
schon geben, auch nur schon um bestehende c Libraries zu verwenden),
wird es ja wohl kaum die Norm sein, bei einem Rust Projekt immer für
alles separat das Interface zu definieren. Im Normalfall ist und bleibt
in Rust die Implementierung auch gleich das Interface, ich kennen kein
Crate, dass das anders handhabt. Abgesehen von ein paar Wrapper für
externe Libs, aber auch das ist eigentlich eine automatisierte
Implementierung des Wrapper für die Lib, und nicht in dem sinne ein
Interface.
Wie Teo oben bereits geschrieben hat, gibt es für Rust bereits einen
passenden Thread:
Beitrag "Rust - ist das hier um zu bleiben?"
Diskutiert diese Dinge also bitte dort weiter.
Frank M. schrieb:> strcmp() liefert im Nicht-Gleichheitsfall negative oder positive Werte> zurück
hihi. Auch Probleme schaffen wo keine sein müssen.
Ich habe in meine langen Programmiererleben noch NIE eine Wahrheit
vorausgesetzt.
Ich führe bei IF THEN o.ä. IMMER den Vergleichswert mit auf.
Also niemals IF X then sondern IMMER if X = true then
Ja das ist altbacken und vielleicht lächerlich. Aber Fakt ist, der
Compiler muss die Bedingung überprüfen und ich muss NICHT wissen was der
Compiler voraussetzt wenn ich es im nicht klar sage.
Und das gilt für ALLE Programmiersprachen die ich bisher programmiert
habe, und da kommt einiges zusammen.
Davon abgesehen hat die Methode auch noch den Vorteil das wenn man
Morgens mit der VB-IDE, Mittags C-IDE + Abends Arduino-IDE oder irgend
eine andere Sprache macht, nicht die Feinheiten des Compilers beachten
muss.
Mich kotzt da schon die Unterschiedliche Bedienung bei der Eingabe an.
Die zu großer Anzahl von Fehlern kommt.
🐧 DPA 🐧 schrieb:> (Und ASM ist ja wohl hier noch schlimmer. Da muss man immer nachsehen,...
Ich sehe es anders herum. Wenn ich mit einer Controllerfamilie arbeiten
will, dann studiere ich natürlich den Befehlssatz und muß später beim
Programmieren sicher nicht öfter in die Doku schaun, als wenn ich
irgendwas in C schreibe. Und es stimmt sicher nicht der Satz: Assembler,
kennste einen, kennste alle...aber so wahnsinnig Unterschiedliches gibt
es doch tatsächlich nicht! Da sind die Unterschiede zwischen einzelnen
Hochsprachen doch auch ähnlich überschaubar. Der für mich größte Schritt
in der Programmierwelt war tatsächlich die OOP. (Natürlich nicht in
Assembler :-)
Gruß Rainer
c-hater schrieb:> ziemlicher Schwachsinn> deswegen ist C Dreck.> Unbrauchbarer Vollrotz> beschissener Syntax
Wir wollen hier über eine Eigenschaft von C diskutieren, nicht über
deine Religion. Deine bereits bekannte Meinung zu C interessiert hier
nicht die Bohne.
Wenn du kotzen willst, mach das auf dem Klo.
Rainer V. schrieb:> Wenn ich mit einer Controllerfamilie arbeiten> will, dann studiere ich natürlich den Befehlssatz
Ich nicht. Wozu auch?
Der Compiler abstrahiert mir den Befehlssatz weg.
So brauche ich nicht ständig neue Sprachen zu lernen.
Schlaumaier schrieb:> Ich führe bei IF THEN o.ä. IMMER den Vergleichswert mit auf.> Also niemals IF X then sondern IMMER if X = true then>> Ja das ist altbacken und vielleicht lächerlich. Aber Fakt ist, der> Compiler muss die Bedingung überprüfen und ich muss NICHT wissen was der> Compiler voraussetzt wenn ich es im nicht klar sage.> Und das gilt für ALLE Programmiersprachen die ich bisher programmiert> habe, und da kommt einiges zusammen.
Da bin ich völlig anderer Meinung. Der Vergleich mit dem Wert true
schlägt für alle truthy-Werte ausser true fehl. Das funktioniert also
nur dann, wenn X ganz sicher ein bool ist, also nur der Wert true oder
der Wert false sein kann. Wir hatten oben schon das Beispiel isalpha()
bei dem das nicht der Fall ist. Ich halte "if X == true" darum für
hochgradig riskant. In vielen anderen Sprachen gibt es zudem mehrere
Werte die falsy sind, zum Beispiel ein leerer String oder eine leere
Liste. In solchen Sprachen gilt dasselbe für den Vergleich mit false.
Die Empfehlung ist daher nicht mit true/TRUE oder false/FALSE zu
vergleichen, oder nur nach expliziter Wandlung in bool.
Für diejenigen, die den Wahrheitsvergleich lieber ausschreiben daher
folgende Makros:
1
#define ISFALSE(val) (!(val))
2
#define ISTRUE(val) (!!(val))
Dann kann man schön altbacken schreiben:
1
if (ISTRUE(X)==TRUE) {...}
Und noch beliebige weitere interessante Kombinationen :)
LG, Sebastian
Schlaumaier schrieb:> Also niemals IF X then sondern IMMER if X = true then
das "==" : geschenkt. Aber wie oben schon gesagt, ist das seit 2000
Jahren abgehandelt, selbst wenn es binär wäre (was es hier nicht ist).
| nur dann, wenn X ganz sicher ein bool ist...
Die Gefahr ist richtig.
Aber ich finde es lesbarer in der Art:
1
intx=....;
2
...
3
if(bool(x)==true)...
bool(x) ist nämlich letztlich dasselbe wie x!=0, aber ich finde es
drückt besser aus was man vorhat.
Nur als Vorschlag...
Abgesehen davon, daß man die unsäglichen #define TRUE und #define FALSE
nicht noch mit noch mehr #define verschlimmbesserrn muß.
Tip: es gibt inzwischen schon seit ein paar Tagen const bool....
Daß man mit Makros viel machen kann, heißt nicht daß man es auch tun
sollte.
(Wenn man schon unbedingt mit true vergleichen will, anstatt einfach if(
x ) zu nehmen).
Egon D. schrieb:> (prx) A. K. schrieb:>>> Das ganze Theater um nicht perfektes C ist ziemlich>> sinnarm, weil das als nutzbares Werkzeug einfach da>> ist und nicht per Federstrich oder Antipathie>> wegdefiniert werden kann.>> Doch, könnte man: Wenn C als Zwischensprache für Compiler> genutzt würde -- wie das ja mit dem Assembler auch schon> funktioniert.
Das wird ja auch öfters gemacht, und es war bei C++-Compilern anfangs
auch üblich.
MaWin schrieb:> Klaus W. schrieb:>> Nur dass der Typ nicht dransteht, sondern sich aus den Operationen>> ergibt.>> Sehr eigenwillige Interpretation des Begriffs "Typ".
Finde ich auch. Ich würde es eher so formulieren: In Assembler gibt's so
Typen wie "irgendwas, das 8 Bit groß ist", "irgendwas, das 16 Bit groß
ist" und "irgendwas, das 32 Bit groß ist". Und ich muss mich selbst drum
kümmern, immer die Instruktionen zu nutzen, die zu dem passen, was ich
da reingeschrieben habe.
🐧 DPA 🐧 schrieb:> Wenn man rustc statt ld zum linken nimmt, ist es> einfacher, aber das ist einfach falsch, ein compiler interface zum> linken zu missbrauchen, da ich keine Rust Projekte machen will, sondern> höchstens Projekte mit Rust.
Das macht man doch bei gcc normalerweise auch. ld nutze ich höchstens
mal unter besonderen Umständen direkt zum linken.
Schlaumaier schrieb:> Ja das ist altbacken und vielleicht lächerlich. Aber Fakt ist, der> Compiler muss die Bedingung überprüfen und ich muss NICHT wissen was der> Compiler voraussetzt wenn ich es im nicht klar sage.
Es klingt wenig vertrauenerweckend, wenn du versuchst, so zu
programmieren, dass du die Sprache nicht verstehen musst.
Klaus W. schrieb:> Aber ich finde es lesbarer in der Art:> int x = ....;> ...> if( bool(x)==true )...>> bool(x) ist nämlich letztlich dasselbe wie x!=0, aber ich finde es> drückt besser aus was man vorhat.
Was hast du denn damit vor? Wenn es hier darum geht zu prüfen, ob x
ungleich 0 ist, fällt mir eigentlich nichts ein, das das besser
ausdrücken würde als x != 0.
Stefan ⛄ F. schrieb:> Selbst auf STM32 brauche ich ab und zu Assembler, nämlich für den NOP> Befehl :-)
Moin,
nutzt Du das NOP für Alignment oder möchtest Du ein Delay einzufügen?
Gruß,
Michael
Michael F. schrieb:> nutzt Du das NOP für Alignment oder möchtest Du ein Delay einzufügen?
Alignment wären ohne weiteren Assembler unwirksam. Ein Assembler-Befehl
(z.B. nop) bewirkt meist, dass der Compiler alles davor davor macht und
alles danach danach.
Rolf M. schrieb:>> Doch, könnte man: Wenn C als Zwischensprache für Compiler>> genutzt würde -- wie das ja mit dem Assembler auch schon>> funktioniert.>> Das wird ja auch öfters gemacht,
Z.B. für Pascal ist mir keine halbwegs verbreitet und
aktuelle Lösung bekannt. p2c stammt von 1991, und die
Entwicklung von gnu-pascal ruht seit 2002, soweit ich
weiss.
Der Shooting-Star FreePascal erzeugt aber Assembler,
kein C. Wird mein Target nicht unterstützt, habe ich
eben Pech gehabt.
> Es klingt wenig vertrauenerweckend, wenn du versuchst,> so zu programmieren, dass du die Sprache nicht> verstehen musst.
M.E. liegt hier der Fokus falsch.
Wenn ich das Problem habe, dass ich ein (mir geeignet
scheinendes) Ausdrucksmittel für einen Sachverhalte
brauche, und ich "verstehe die Sprache" und lerne, dass
die Sprache kein solches Ausdrucksmittel hat -- dann
hat das "Verstehen der Sprache" nichts zur Lösung meines
Problems beigetragen: Ich habe immer noch kein Ausrucks-
mittel!
Jetzt gibt es mehrere Möglichkeiten:
1. Ich wechsele die Sprache.
Das ist aber, wie wir wissen, in vielen Fällen keine
Option.
2. Ich verwende statt der gesuchten geeigneten Ausdrucks-
mittel halt ungeeignete.
Das ist das, was normal sozialisierte C-Programmierer
tun: Sie finden sich mit der Lage ab.
3. Ich versuche, irgendwie doch geeignete Ausdrucksmittel
zu schaffen.
Wer 3. versucht, hat daher nicht automatisch "die Sprache
nicht verstanden" -- er ist nur zu 2. nicht bereit.
A. S. schrieb:> Ein Assembler-Befehl> (z.B. nop) bewirkt meist, dass der Compiler alles davor davor macht und> alles danach danach.
Nur bei Architekturen, bei denen sich jeder Befehl so verhält.
Andernfalls benötigt man spezielle Barrier-Befehle, NOP erfüllt diese
Rolle nicht.
A. S. schrieb:> Alignment wären ohne weiteren Assembler unwirksam.
Und ein NOP als Delay kann in Cortex-M MCUs unwirksam sein ;-)
(darauf zielte meine Frage eigentlich ab...)
In der Arm Doku für Cortex-M0 bis Cortex-M7 wird erwähnt, dass ein NOP
aus der Pipeline entfernt werden kann, bevor es Ausführungszeit kostet.
Da keine Randbedingungen spezifiziert sind, wann das passieren kann,
sollte man was anderes nutzen, wenn man verlässlich einen Zyklus Delay
benötigt.
Gruß,
Michael
Egon D. schrieb:>>> Doch, könnte man: Wenn C als Zwischensprache für Compiler>>> genutzt würde -- wie das ja mit dem Assembler auch schon>>> funktioniert.>>>> Das wird ja auch öfters gemacht,>> Z.B. für Pascal ist mir keine halbwegs verbreitet und> aktuelle Lösung bekannt. p2c stammt von 1991, und die> Entwicklung von gnu-pascal ruht seit 2002, soweit ich> weiss.
Es gab mal f2c.
Das hat Fortran 77 in äquivalentes C konvertiert.
Damit hat man auf jedem System Fortran, mehr braucht man ja nicht.
Es hat sich mittlerweile erledigt, weil der gcc ja auch inzwischen
Fortran direkt kann (und das auch besser, z.B. aktuelleres Fortran).
Rolf M. schrieb:> Klaus W. schrieb:>> Aber ich finde es lesbarer in der Art:>> int x = ....;>> ...>> if( bool(x)==true )...>>>> bool(x) ist nämlich letztlich dasselbe wie x!=0, aber ich finde es>> drückt besser aus was man vorhat.>> Was hast du denn damit vor? Wenn es hier darum geht zu prüfen, ob x> ungleich 0 ist, fällt mir eigentlich nichts ein, das das besser> ausdrücken würde als x != 0.
Ich selbst würde es nicht so schreiben, sondern z.B. gleich if(x)...,
auch wenn x eine int ist oder ein Zeiger.
Was du von mir zitiert hast, war eine Antwort auf:
Sebastian W. schrieb:> Für diejenigen, die den Wahrheitsvergleich lieber ausschreiben daher> folgende Makros:> #define ISFALSE(val) (!(val))> #define ISTRUE(val) (!!(val))>> Dann kann man schön altbacken schreiben: if (ISTRUE(X)==TRUE) {...}
Da soll ein numerisches X als logischer Wert verwendet und mit einem
logischen TRUE verglichen werden.
Angenommen, man möchte das numerische X als logischen Wert nutzen und
dabei explizit mit ...==TRUE... ausdrücken (so von Sebastian W.
vorgeschlagen), dann hätte ich den erwähnten Verbesserungsvorschlag:
nicht mit einem ominösen Makro das X in den Bereich [0,1] zwängen
sondern mit dem was C dafür bietet: bool(X). Das ist Standard, braucht
keine Makros und drückt klar aus, daß man aus dem numerischen X eine
bool machen will.
Hallo,
Egon D. schrieb:> 2. Ich verwende statt der gesuchten geeigneten Ausdrucks-> mittel halt ungeeignete.> Das ist das, was normal sozialisierte C-Programmierer> tun: Sie finden sich mit der Lage ab.
Was ist die Alternative? Etwa:
> 3. Ich versuche, irgendwie doch geeignete Ausdrucksmittel> zu schaffen.
Das führt dann zu Sprachen wie z.B. C++, die durch ihre Komplexität in
der Gänze kaum noch zu beherrschen sind und durch ihre schiere Größe
den größten Vorteil gegenüber dem "unvollständigen" C verlieren, nämlich
auch auf "kleiner" Hardware lauffähig zu sein.
Bei aller berechtigten Kritik an C sollte man sich immer vor Augen
halten wofür die Sprache ursprünglich gedacht war. Wofür die Sprache
heute noch alles verwendet wird, sollte man ihr nicht anlasten. Wer mit
den Unzulänglichkeiten der Sprache nicht leben kann oder nicht zurecht
kommt, hat jeder Zeit die Möglichkeit auf andere, besser entworfene,
Sprachen auszuweichen.
rhf
P.S.
Die Tatsache, das in C immer noch so viel Software erstellt wird, zeigt
mir das die Vorteile der Sprache ihre Schwächen offensichtlich deutlich
überwiegen.
Roland F. schrieb:> Die Tatsache, das in C immer noch so viel Software erstellt wird, zeigt> mir das die Vorteile der Sprache ihre Schwächen offensichtlich deutlich> überwiegen.
Nicht wirklich.
Es ist halt so das es einfacher ist, sich an "Unzulänglichkeiten" zu
gewöhnen, als einen neue Sprache für eine bestimmte Anwendung zu lernen.
Weshalb ich halt BASIC-Fan bin. Ich kann das in ca. 30 Dialekten und
programmiere was ich will auf allen Geräten die ich habe und je hatte.
Inkl. Ei-fon, Android, Raspberry, Linux, Windows etc. Sogar mein
Taschenlaptop (mit Dos 2.11) habe ich damals damit Programmiert.
Stefan ⛄ F. schrieb:> Wir wollen hier über eine Eigenschaft von C diskutieren, nicht über> deine Religion...
O ha, starker Tobak.
Nun, C ist eine Programmiersprache, die von Leuten (auf Basis von BCPL)
geschaffen wurde, welche eben nicht den akademischen Überblick hatten
wie z.B. jemand wie Wirth. Das merkt man auch noch heutzutage, obwohl
durch die ANSI-Überarbeitung das Allerschlimmste in C getilgt worden
ist.
So ist gar vieles in C eben nicht auf Logik gebaut, sondern auf Dekret
("das ist hier eben so!") und folglich braucht C mehr
Einarbeitungs-Aufwand als z.B. Pascal.
Was dabei ein bissel verloren geht, ist die logische Verbindung zur
Mathematik. Dabei ist u.a. der Datentyp "boolean", also ein einbittiger
Datentyp in C durch eine Konvention ersetzt (0=false, alles
andere=true), die zwar praktisch recht ordentlich benutzbar ist durch
das in eigentlich allen Rechenwerken vorhandene Zero-Flag, aber bei der
hier gestellten Frage nur zu der logisch unbefriedigenden Antwort führen
kann: Das ist hier eben so.
Und da 1 nicht 0 ist, ist es true, genau so wie 2 oder auch 4711 ebenso
true sind. Eigentlich ist das für den Anwendungs-Programmierer völlig
egal, genau so, wie es eigentlich egal ist, ob man ein "char" als
vorzeichenlos ansieht oder nicht. Relevant wird das nur dann, wenn man
damit etwas Mathematisches betreiben, also damit rechnen will. Dann
fängt der Zoff an, wenn man fragt, welchen numerischen Wert 4711+true
ergeben würde. An solchen Stellen stößt man mit der Nase auf die vielen
Schlampigkeiten in der Konstruktion von C.
W.S.
Klaus W. schrieb:> Ich selbst würde es nicht so schreiben, sondern z.B. gleich if(x)...,> auch wenn x eine int ist oder ein Zeiger.
Für int habe ich mir das abgewöhnt, gerade weil hier x!=0 die Intention
viel besser wiedergibt.
Bei Zeigern mache ich es aber auch. Da passt das für mich besser zu
Intention. if (!p) bedeutet eben soviel wie "wenn kein Objekt
vorhanden…).
Egon D. schrieb:> Klaus W. schrieb:>>> mit dem was C dafür bietet: bool(X). Das ist Standard>> In reinem C (ohne PlusPlus)?> Seit wann? Und wo steht das?
In C müsste es (bool)X heißen, in C++ wäre heute wohl eher bool{X} en
vogue, allerdings schlägt das dann fehl, weil das eine "narrowing
conversion" wäre, also mit Informationsverlust verbunden. Wenn man es
dann trotzdem will, sollte es eher ein static_cast<bool>(X) sein. Casts
im C- oder Konstruktor-Stil sollte man eher vermeiden.
Roland F. schrieb:>> 3. Ich versuche, irgendwie doch geeignete>> Ausdrucksmittel zu schaffen.>> Das führt dann zu Sprachen wie z.B. C++,
Nicht unbedingt.
Diese "geeigneten Ausdrucksmittel" können meinetwegen
auch ein paar C-Makros sein -- Hauptsache, sie schirmen
mich von den Implementierungsdetails von C ab, die ich
nie wissen wollte.
> durch ihre schiere Größe den größten Vorteil gegenüber> dem "unvollständigen" C verlieren, nämlich auch auf> "kleiner" Hardware lauffähig zu sein.
Das Argument geht fehl -- nicht der COMPILER muss auf
der kleinen Hardware lauffähig sein, sondern das
COMPILAT. Programme für Mikrocontroller werden i.d.R.
mittels Crosscompilation erstellt.
> Bei aller berechtigten Kritik an C sollte man sich> immer vor Augen halten wofür die Sprache ursprünglich> gedacht war.
Ja: Für Systemprogrammierung.
> Wofür die Sprache heute noch alles verwendet wird,
Mikrocontrollerprogrammierung ist zu weiten Teilen
Systemprogrammierung, und gerade auf µC gibt es zu C
keine echte Alternative. Das wurde hier schon mehrfach
in epischer Breite diskutiert.
Wenn ich an irgend einem Tool auf dem PC herumbastele,
verwende ich sowieso Tcl oder FreePascal.
> Wer mit den Unzulänglichkeiten der Sprache nicht> leben kann oder nicht zurecht kommt, hat jeder Zeit> die Möglichkeit auf andere, besser entworfene,> Sprachen auszuweichen.
Genau das stimmt eben nicht, wenn wir von µC reden.
> Die Tatsache, das in C immer noch so viel Software> erstellt wird, zeigt mir das die Vorteile der Sprache> ihre Schwächen offensichtlich deutlich überwiegen.
Das stimmt -- aber das ist mangels Alternative auch
nicht besonders schwierig.
Egon D. schrieb:> Wenn ich an irgend einem Tool auf dem PC herumbastele, verwende ich> sowieso Tcl oder FreePascal.
Ist denn die Behandlung von booleschen Werten in Tcl arg viel anders als
in C?
Und ist das Typsystem von Tcl nicht sogar noch laxer als in C
(insbesondere was implizite Konvertierungen betrifft)?
Yalu X. schrieb:> Und ist das Typsystem von Tcl nicht sogar noch laxer als in C> (insbesondere was implizite Konvertierungen betrifft)?
Das Typsystem von Tcl ist extrem streng: Es gibt Skalare und
Dictionaries, und diese beiden Typen werden sogar syntaktisch
unterschieden.
Skalare können allerdings Zahlen, Strings oder sogar Funktionen sein :)
LG, Sebastian
Yalu X. schrieb:> Egon D. schrieb:>> Wenn ich an irgend einem Tool auf dem PC herumbastele,>> verwende ich sowieso Tcl oder FreePascal.>> Ist denn die Behandlung von booleschen Werten in Tcl> arg viel anders als in C?
Die Behandlung (sprich: die Operatoren) sind identisch.
Die Codierung der Wahrheitswerte war aber von Anfang
an besser: Man kann einfach "true" bzw. "false" schreiben.
Auf die Idee, so etwas Schräges wie
1
2
set x 17
3
if { $x } then { puts "wahr" } else { puts "falsch" }
zu schreiben, bin ich bisher nie gekommen. -- Gerade
mal probiert: Ausschrift ist "wahr".
Es funktioniert also wie in C.
> Und ist das Typsystem von Tcl nicht sogar noch> laxer als in C
Schon -- aber im Gegensatz zu C meldet sich der
Interpreter, wenn ich versuche, aus "Bundeskanzler"
die Wurzel zu ziehen.
> (insbesondere was implizite Konvertierungen betrifft)?
Naja, so arg viel kann nicht schiefgehen: Wenn man
Strinfunktionen auf Zahlen anwendet, werden die halt
vorher in Strings konvertiert, und wenn man versucht,
mit Strings zu rechnen, gibt's eine Fehlermeldung,
wenn die Strings keine Zahlen darstellen.
Pointer gibt's nicht und braucht man nicht.
Egon D. schrieb:>> Und ist das Typsystem von Tcl nicht sogar noch>> laxer als in C>> Schon -- aber im Gegensatz zu C meldet sich der> Interpreter, wenn ich versuche, aus "Bundeskanzler"> die Wurzel zu ziehen.
In C ist es halt der Compiler, der meckert :)
Rolf M. schrieb:> In C müsste es (bool)X heißen,
Ach soooo. Hmm.
Ich habe gerade etwas getan, was dem lebhaften Fortgang
der Diskussion sehr hinderlich sein dürfte: Ich habe
einen Blick in den ANSI-C-Standard geworfen.
Habe ich das richtig verstanden?
1. Absatz 3.3.3 ("unäre arithmetische Operatoren") sagt u.a.:
Das Ergebnis des logischen Negationsoperators ! ist 0,
wenn der Wert des Operanden verschieden von 0 ist, und 1,
wenn der Wert des Operanden 0 ist.
2. Absatz 3.3.8 ("Vergleichsoperatoren") sagt: Der Ausdruck
soll "1" liefern, wenn die Relation gilt, und "0", wenn
sie nicht gilt.
(Betrifft also "<", "<=", ">", ">=")
3. Absatz 3.3.9 ("Gleichheitsoperatoren") sagt: Abgesehen von
der niedrigeren Priorität analog zu 3.3.8
(Betrifft "==" und "!=")
4. 3.3.13 ("&&") und 3.3.14 ("||") sagen gleichfalls, dass
diese Operatoren nur entweder 0 oder 1 zum Ergebnis
haben dürfen.
Das bedeutet für meinen schwachen Verstand: Wenn kein
Operator in der Liste oben fehlt, dann liefern alle
Vergleichs- und sonstigen booleschen Operatoren nur
entweder 0 oder 1 als Ergebnis, und nix anderes.
Wenn man also unter Verwendung der booleschen Operatoren
einen booleschen Ausdruck baut, dann hat der garantiert
nur 0 oder 1 zum Ergebnis, und nix anderes.
Daher ist es berechtigt, zu sagen, dass 0 den Wahrheitswert
"falsch" und 1 den Wahrheitswert "wahr" repräsentiert.
Dem widerspricht auch nicht, dass Bedingungen wie "if" etc.
auch Ganzzahlen >1 als "wahr" interpretieren, denn diese
Ganzzahlen sind ja eben GANZZAHLEN , die nicht als Ergebnis
eines booleschen Ausdruckes entstehen können, und keine
Wahrheitswerte. Man kann diese Großzügigkeit in der Prüfung
von Bedingungen mögen oder hassen -- aber das hat nichts
mit Wahrheitswerten und deren Darstellung zu tun.
Genauso schräg ist die Klage darüber, dass (3==7) etwas
ganz anderes liefert als ((bool)3==(bool)7)... ich meine,
was ist denn das für eine Zahlenmystik? Was soll denn
sonst herauskommen?
Fazit: Mir will scheinen, dass es bei der Auswertung
boolescher Ausdrücke überhaupt kein Problem gibt. Probleme
können auftreten, wenn arithmetische Ausdrücke verwendet
werden, wo inhaltlich boolesche passend wären -- in
Bedingungen zum Beispiel.
Aber die Lösung kann ja unmöglich so simpel sein, einfach
überall dort, wo ein Wahrheitswert gebraucht wird, auch
einen korrekten booleschen Ausdruck hinzuschreiben.
Was also übersehe ich?
Du übersiehst den Drang mancher Leute, sich mit Tausend #define
irgendwas zurechtzubasteln, was erstmal geht aber nur Verwirrung
stiftet.
Sonst hast du recht - es ist ganz schlicht in C, und auch nicht schwer
zu verstehen.
Logische Ausdrücke liefern (als int betrachtet) immer 0 oder 1.
Bei der Verwendung von Zahlen oder Zeigern wird 0 als false betrachtet,
alles andere als true.
Mehr muß man nicht wissen.
Egon D. schrieb:> Was also übersehe ich?
Nichts, du hast damit meine Aussage wiederholt und begründet:
Stefan ⛄ F. schrieb:> Das ist doch ganz einfach:> - True hat den Wert 1, false hat den Wert 0> - Alle Werte ungleich 0 sind wahr
Egon D. schrieb:> Das bedeutet für meinen schwachen Verstand: Wenn kein> Operator in der Liste oben fehlt, dann liefern alle> Vergleichs- und sonstigen booleschen Operatoren nur> entweder 0 oder 1 als Ergebnis, und nix anderes.
Genau so ist es.
> Fazit: Mir will scheinen, dass es bei der Auswertung> boolescher Ausdrücke überhaupt kein Problem gibt.
Sagen wir mal so: Die Probleme, die einige hier sehen, sind rein
akademischer Art. Ich hatte diese Probleme noch nie, obwohl ich, bevor
ich C lernte, hauptsächlich Pascal gemacht habe, das im Gegensatz zu C
klar zwischen Boolean und Integer unterscheidet.
Egon D. schrieb:> Was also übersehe ich?
Nichts. Es hat doch auch niemand etwas anderes behauptet. Es gab nur ein
paar, die zur reinen optischen Leseerfahrung Ausdrücke z.B. im if in 0/1
wandeln möchten um dann auch auf == true abfragen zu dürfen.
Wer das will, kann das machen, C kam viele Jahre ohne bool aus und die
Regelung mit 0 (nicht erfüllt) und 1 (erfüllt) als Ergebnis boolscher
Ausdrücke deckt sich mit 0 (nicht erfüllt) und !=0 (erfüllt) bei
Abfragen.
Eine Sonderstellung nehmen hier Bitfelder ein, die bei "int" oder Bool
keinen Wert von 1 annehmen können. Das spielt in der Praxis keine Rolle,
Warnungen sind dementsprechend angepasst oder anpassbar. Ein Vergleich
auf "true" schlägt dann aber immer fehl.
Klaus W. schrieb:> Sonst hast du recht - es ist ganz schlicht in C,
Ja, offensichtlich.
> und auch nicht schwer zu verstehen.
Das sehe ich etwas anders: Ob etwas schwer zu verstehen
ist, hängt nicht nur von der Kompliziertheit des
Sachverhaltens ab, sondern auch von der Güte der Erklärung :)
Mir steht nur die (zweite) deutsche Ausgabe des K&R zur
Verfügung; das Buch ist zwar als historisches Dokument
interessant, aber das VERSTEHEN kommt in der Regel erst
bei den Diskussionen hier auf µC.net :)
Stefan ⛄ F. schrieb:> Nichts, du hast damit meine Aussage wiederholt> und begründet:>> Stefan ⛄ F. schrieb:>> Das ist doch ganz einfach:>> - True hat den Wert 1, false hat den Wert 0>> - Alle Werte ungleich 0 sind wahr
Das ist sachlich zwar richtig, unterschlägt aber den
Punkt, auf den es mir entscheidend ankam: Für das
BERECHNEN von Wahrheitswerten gelten andere Regeln
als für das AUSWERTEN von Bedingungen durch Steuer-
anweisungen.
Ein boolescher Ausdruck kann nie das Ergebnis "3"
liefern -- aber ein "if" akzeptiert eine "3" problemlos
als Argument.
Egon D. schrieb:> Mir steht nur die (zweite) deutsche Ausgabe des K&R zur> Verfügung; das Buch ist zwar als historisches Dokument> interessant, aber das VERSTEHEN kommt in der Regel erst> bei den Diskussionen hier auf µC.net :)
Früher(tm), als das Usenet noch von Bedeutung war, war ich oft in der
newsgroup comp.lang.c. Da waren dort auch richtige C-Profis wie Dan Pop,
Steve Summit oder Richard Heathfield unterwegs. Dort hab ich wahnsinnig
viel über C gelernt.
Yalu X. schrieb:>> Fazit: Mir will scheinen, dass es bei der Auswertung>> boolescher Ausdrücke überhaupt kein Problem gibt.>> Sagen wir mal so: Die Probleme, die einige hier sehen,> sind rein akademischer Art.
Das sehe ich nicht so.
Ich verstehe den Sinn von vielem, was ich im K&R lese,
tatsächlich erst dadurch, dass es hier diskutiert wird.
> Ich hatte diese Probleme noch nie,
Lass' es mich so ausdrücken: Ich halte Dich, was logisch-
mathematische Fragen angeht, nicht für eine allgemein
anwendbare Referenz :)
> obwohl ich, bevor ich C lernte, hauptsächlich Pascal> gemacht habe, das im Gegensatz zu C klar zwischen> Boolean und Integer unterscheidet.
Schätzungsweise nicht "obwohl", sondern "weil". Wer
weiss, wie es richtig geht, kann in der Praxis auch
schlampen, ohne gleich Fehler zu machen -- wer es
aber von vornherein schlampig gelernt hat, kommt nie
auf einen grünen Zweig.
Egon D. schrieb:> Das ist sachlich zwar richtig, unterschlägt aber den> Punkt, auf den es mir entscheidend ankam: Für das> BERECHNEN von Wahrheitswerten gelten andere Regeln> als für das AUSWERTEN von Bedingungen durch Steuer-> anweisungen.> Ein boolescher Ausdruck kann nie das Ergebnis "3"> liefern -- aber ein "if" akzeptiert eine "3" problemlos> als Argument.
Nein, da wird gar nichts unterschlagen.
Vergleichsoperatoren liefern true(1) oder false(0). Das habe ich nicht
ausdrücklich geschrieben, da es selbstverständlich ist und auch überall
so dokumentiert ist.
Dein zweiter Punkt, dass if eine 3 akzeptiert ergibt sich aus meiner
Aussage, dass alle Werte ungleich 0 wahr sind.
Vermutlich ist das zu simpel, um von einigen hier akzeptiert zu werden.
Wasser ist nass, aber nicht alles nasse ist Wasser. Das kann man auch
einfach mal hinnehmen, oder verrückt zu werden.
Teo D. schrieb im Beitrag #6720075:
> Oder wo in den> Tiefen von C, verbirgt sich da der Pferdefuß?
Seit über(?) 50 Jahren ist klar, das ein if(irgendwas) völlig ausreicht
und ein if(irgendwas == true) ganz schnell ins verderben führt.
Das gilt für altes C, frisches C, und auch für C++.
Dabei ist völlig egal, obs einen Boolean Datentype kennt, oder auch
nicht.
Mehr Problem ist da nicht.
Außer, dass es noch nicht in jedem seine Hirnwindungen angekommen ist.
Egon D. schrieb:> Ich verstehe den Sinn von vielem, was ich im K&R lese,> tatsächlich erst dadurch, dass es hier diskutiert wird.
Vielleicht solltest Du bei allem, was Du da liest, Dich fragen, wie man
es einfacher machen könnte, dass es weniger Seiten im Standard oder
einer Beschreibung braucht. Und nicht immer in UB oder ID ausartet.
Beispiel: Natürlich kann man NIL für einen uninitialisierten Ptr
einführen. Doch dann muss ich zusätzlich dieses NIL erklären UND
beschreiben, wie ich es z.B. von einem gültigen 16-bit-Ptr
unterscheiden kann.
So blöd es klingt, ziel war auch damals schon die minimale Überraschung
gewesen.
Die in C fehlende Trennung von Integers und Boolean wirkt sich dort aus,
wo man Booleans in Vergleichen verwendet, ohne darauf zu achten, ob die
andere Seite auch ein Boolean ist. Sprachen mit Trennung zeigen einem
dann den Vogel, weil die Datentypen nicht zueinander passen. C nicht.
Wer also partout auf solche Vergleiche besteht, sollte "true" nur in
Zuweisungen verwenden, nie in Vergleichen. Wer es nicht lassen kann,
fährt mit if(x != false) besser als mit if(x == true). Ist aber eher was
für Leute, die damit dokumentieren wollen, dass sie C nicht mögen, weil
sich dem kundigen Leser die Zehennägel kräuseln.
A. S. schrieb:> Egon D. schrieb:>> Was also übersehe ich?>> Nichts. Es hat doch auch niemand etwas anderes> behauptet.
Oh doch.
Bereits in der ursprünglichen Fragestellung taucht die
Behauptung auf, man könne ja gar keinen festen Wert
für "true" angeben, weil int schließlich mehr als 0
und 1 darstellen kann.
> Es gab nur ein paar, die zur reinen optischen> Leseerfahrung Ausdrücke z.B. im if in 0/1 wandeln> möchten um dann auch auf == true abfragen zu> dürfen.
Mag wohl sein -- der Knackpunkt ist: WAS FÜR
Ausdrücke?
Einen booleschen Ausdruck erstmal in 0/1 zu wandeln,
um dann auf == true abzufragen, hat m.E. überhaupt
keinen Sinn.
Und wenn es um ganzzahlige Ausdrücke geht -- nun ja,
man könnte sich ja vielleicht so als Zugeständnis
an's dritte Jahrtausend doch mal dazu entschließen,
einen booleschen Ausdruck ins Argument von "if" zu
schreiben, und keinen ganzzahligen.
Was ist an "if (errno>0)" so viel entsetzlicher als
an "if (errno)" -- außer dass es allgemeinverständlich
ist?
> Wer das will, kann das machen, C kam viele Jahre ohne> bool aus und die Regelung mit 0 (nicht erfüllt) und 1> (erfüllt) als Ergebnis boolscher Ausdrücke deckt sich> mit 0 (nicht erfüllt) und !=0 (erfüllt) bei Abfragen.
Ja -- aber das ist nicht der Punkt.
Es wird allerorten -- z.B. im K&R -- so penetrant
betont, dass man ganzzahlige Ausdrücke als Argumente
für Bedingungen verwenden kann , dass völlig
untergeht, dass man das nicht tun muss !
Der (m.E. schlechte und schlampige) Stil wird so
penetrant angepriesen, dass man völlig überliest,
dass man den Käse nicht mitmachen muss!
Egon D. schrieb:> dass völlig untergeht, dass man das nicht tun muss !
Man muss C nicht verwenden...
> Was ist an "if (errno>0)" so viel entsetzlicher als> an "if (errno)" -- außer dass es allgemeinverständlich> ist?
...aber man es dennoch tut, dann sollte man sich dran gewöhnen, dass es
C ist.
Wer if(errno) nicht als allgemeinverständlich betrachtet, der hat m.E.
ein Problem mit dieser Sprache.
Konsequenter wäre es hier, nicht if(errno>0) zu schreiben, sondern
abstrahiert von konkreten Werten sowas wie if(success(errno)), und
success() an zentraler Stelle als Layer zwischen Sprachebenen
definieren.
Egon D. schrieb:> Es wird allerorten -- z.B. im K&R -- so penetrant> betont, dass man ganzzahlige Ausdrücke als Argumente> für Bedingungen verwenden kann , dass völlig> untergeht, dass man das nicht tun muss !> Der (m.E. schlechte und schlampige) Stil wird so> penetrant angepriesen, dass man völlig überliest,> dass man den Käse nicht mitmachen muss!
Nochmal:
In C ist ein logischer Ausdruck ein ganzzahliger Ausdruck, und zwar mit
dem Wert 0 oder 1.
(a<b) ist eine ganze Zahl, (&i==0) ebenso, (3.1415926535>2.718281828)
auch.
Nur daß diese Ausdrücke halt nicht irgendeine Zahl liefern, sondern
entweder 0 oder 1.
Sobald du also if( a>b )... schreibst, verwendest du einen ganzzahligen
Ausdruck als Bedingung.
(prx) A. K. schrieb:> Egon D. schrieb:>> dass völlig untergeht, dass man das nicht tun>> muss !>> Man muss C nicht verwenden...
Warum redest Du hier wider besseren Wissens?
Für Mikrocontroller gibt es keine praktikable
Alternative; das ist hier schon oft genug
durchgekaut worden.
>> Was ist an "if (errno>0)" so viel entsetzlicher>> als an "if (errno)" -- außer dass es>> allgemeinverständlich ist?>> ...aber man es dennoch tut, dann sollte man sich> dran gewöhnen, dass es C ist.
Bei allem Respekt: Was ich sollte , das mache ich
davon abhängig, wie gut die Begründung ist.
Kleiner Tipp: "Das haben wir schon immer so gemacht!
Das haben wir noch nie so gemacht! Da könnte ja jeder
kommen!" sind keine guten Begründungen.
> Wer if(errno) nicht als allgemeinverständlich> betrachtet, der hat m.E. ein Problem mit dieser> Sprache.
Und wer das -- unter der Voraussetzung, dass errno
ein Integer ist -- als vernünftig und sinnvoll
ansieht, hat m.E. ein Problem mit mathematischer
Logik.
Arduino Fanboy D. schrieb:> Teo D. schrieb im Beitrag #6720075:>> Oder wo in den>> Tiefen von C, verbirgt sich da der Pferdefuß?>> Seit über(?) 50 Jahren ist klar, das ein if(irgendwas) völlig ausreicht> und ein if(irgendwas == true) ganz schnell ins verderben führt.> Das gilt für altes C, frisches C, und auch für C++.> Dabei ist völlig egal, obs einen Boolean Datentype kennt, oder auch> nicht.
Das war nicht meine Frage. Die war einfach nur dämlich und wurde deshalb
gelöscht. :D
Egon D. schrieb:> Was ist an "if (errno>0)" so viel entsetzlicher als> an "if (errno)" -- außer dass es allgemeinverständlich> ist?
Der Schrecken kommt mit "errno = -4".
Stefan ⛄ F. schrieb:> Egon D. schrieb:>> hat m.E. ein Problem mit mathematischer Logik.>> C ist nun einmal nicht Mathe, sonder C.
Wer kennt ne Sprache wo das anders is?
Ich mein ja BASIC ZX81, aber das is nu wirklich zu lange her.
Klaus W. schrieb:> Egon D. schrieb:>> Es wird allerorten -- z.B. im K&R -- so penetrant>> betont, dass man ganzzahlige Ausdrücke als Argumente>> für Bedingungen verwenden kann , dass völlig>> untergeht, dass man das nicht tun muss !>> Der (m.E. schlechte und schlampige) Stil wird so>> penetrant angepriesen, dass man völlig überliest,>> dass man den Käse nicht mitmachen muss!>> Nochmal:> In C ist ein logischer Ausdruck ein ganzzahliger> Ausdruck, und zwar mit dem Wert 0 oder 1.
Korrekt. Logische Ausdrücke sind SPEZIELLE ganzzahlige
Ausdrücke (nämlich solche, die nur 0 oder 1 liefern).
Mit "ganzzahliger Ausdruck" war im oben zitierten
Text ein ALLGEMEINER ganzzahliger Ausdruck gemeint,
also einer, der auch Werte größer 1 liefern kann.
Ich dachte, das sei klar.
Egon D. schrieb:> Korrekt. Logische Ausdrücke sind SPEZIELLE ganzzahlige> Ausdrücke (nämlich solche, die nur 0 oder 1 liefern).
Nö, das sind und bleiben Boolsche Ausdrücke und haben mit Zahlen nix am
Hut. Nur Wahr oder Falsch, lässt sich halt nur recht schlecht ins RAM
tackern!
Der Rest ist einfach nur Bequemlichkeit.
Egon D. schrieb:> hat m.E. ein Problem mit mathematischer Logik.
Da ich in APL programmieren lernte, war die Versuchung gering, C als
Verwirklichung mathematischen Denkens zu verstehen. ;-)
Jeder Sprache ihre Sphäre. C ist nicht von Mathematik abgeleitet,
sondern von Praktikabilität zur Entstehungszeit. Nicht Abstraktion,
sondern relativ dicht am Konkreten. Das ist ihr Konzept - bis heute.
Daher auch mein Vorschlag vorhin bei errno: Wenn Abstraktion, dann auch
von konkreten Werten. Das reduziert die Abhängigkeit von "magic numbers"
auf eine zentrale Stelle.
Stefan ⛄ F. schrieb:> Egon D. schrieb:>> hat m.E. ein Problem mit mathematischer Logik.>> C ist nun einmal nicht Mathe, sonder C.
Das Problem ist nicht C -- die Sprache lässt ja eine
andere Ausdrucksweise zu, wie wir jetzt wissen.
Das Problem sind die C-Programmierer, wie diese
Diskussion lehrt.
Wer gegen ihre Initiationsriten aufmuckt, wird
weggebissen.
Teo D. schrieb:> Egon D. schrieb:>> Was ist an "if (errno>0)" so viel entsetzlicher als>> an "if (errno)" -- außer dass es allgemeinverständlich>> ist?>> Der Schrecken kommt mit "errno = -4".
Ja... okay. Stattgegeben. Dann halt "(errno!=0)".
Egon D. schrieb:> as Problem ist nicht C> Das Problem sind die C-Programmierer
Ich würde sagen beides ist das Problem.
Ewiggestrige Programmierer, die Verlustängste haben und an ihrer
ewiggestrigen Sprache krampfhaft festhalten.
Teo D. schrieb:> Egon D. schrieb:>> Korrekt. Logische Ausdrücke sind SPEZIELLE ganzzahlige>> Ausdrücke (nämlich solche, die nur 0 oder 1 liefern).>> Nö, das sind und bleiben Boolsche Ausdrücke
Jein -- unsere (Klaus' und meine) Ausdrucksweise ist
schlampig: Die Ausdrücke sind im Prinzip tatsächlich
boolesche Ausdrücke, denn sie verwenden ja boolesche
Operatoren. Deren Ergebnis ist aber (leider) ganz-
zahlig.
> und haben mit Zahlen nix am Hut.
Das wäre schön und logisch -- ist aber in C nicht so.
Teo D. schrieb:>> C ist nun einmal nicht Mathe, sonder C.> Wer kennt ne Sprache wo das anders is?
Darauf wollte ich hinaus. Programmiersprachen definieren ihr eigenes
Regelwerk. Die Tatsache, dass es da viele Gemeinsamkeiten mit anderen
bekannten Regelwerken gibt, wollte keinen Entwickler dazu verleiten, die
Regeln der Sprache zu missachten.
Die meisten Softwareentwickler benutzen regelmäßig viele
unterschiedliche Programmiersprachen mit unterschiedlichen Regeln. Wer
das nicht auseinander halten kann der ist kein Softwareentwickler.
Sorry, ist so.
Egon D. schrieb:> Was ist an "if (errno>0)" so viel entsetzlicher als> an "if (errno)" -- außer dass es allgemeinverständlich> ist?
Es bietet keinen Mehrwert beim Lesen. Deutlich wird es bei
if(keyPressed) oder if(KeyPressed())
Deutlich wird es auch bei "if(3>4)" da schreibt auch niemand
"if((3>4)!=0)".
Warum sollte keyPressed anders behandelt werden wie 3>4 ?
"Wenn 3 > 4 ist" ist besser als "Wenn (3>4) wahr ist"
Genauso ist "wenn taste gedrückt ist" besser als "wenn Taste gedrückt
wahr ist". Im echten Leben redet doch auch niemand so.
(prx) A. K. schrieb:> Egon D. schrieb:>> hat m.E. ein Problem mit mathematischer Logik.>> Da ich in APL programmieren lernte, war die Versuchung> gering, C als Verwirklichung mathematischen Denkens> zu verstehen. ;-)
Okay... Du erwähntest dies früher schon, glaube ich. :)
> Jeder Sprache ihre Sphäre. C ist nicht von Mathematik> abgeleitet, sondern von Praktikabilität zur> Entstehungszeit. Nicht Abstraktion, sondern relativ> dicht am Konkreten. Das ist ihr Konzept - bis heute.
Damit habe ich auch kein Problem.
> Daher auch mein Vorschlag vorhin bei errno: Wenn> Abstraktion, dann auch von konkreten Werten.
Meinetwegen.
Ändert aber nix daran, dass ich es für schlechten Stil
halte, mit einer binären Fallunterscheidung auf Ausdrücke
loszugehen, die mehr als zwei zulässige Belegungen haben.
> Das reduziert die Abhängigkeit von "magic numbers"> auf eine zentrale Stelle.
Okay, meinetwegen: "if (errno==fehlerfrei) { ..."
mit passender Definition von fehlerfrei.
Klaus W. schrieb:> Logische Ausdrücke liefern (als int betrachtet) immer...
Das war von Anfang an unbestritten, aber schön daß auch du es nochmal
formuliert hast.
Der Knackpunkt in C besteht darin, daß man dort die Freiheit hat,
überhaupt Integerarithmetik damit zu betreiben. Das ist genau so wie die
numerische Benutzung von Textzeichen aka 'char'. Es geht ja, aber es ist
jemandem, der ordentliche logische Verhältnisse gewohnt ist, zu Recht
suspekt.
W.S.
A. S. schrieb:> Egon D. schrieb:>> Was ist an "if (errno>0)" so viel entsetzlicher als>> an "if (errno)" -- außer dass es allgemeinverständlich>> ist?>> Es bietet keinen Mehrwert beim Lesen.
Doch, mir schon.
Ich finde umgekehrt "if (errno)" in sich widersprüchlich.
"if" stellt eine binäre Fallunterscheidung dar; das ist
eine aussagenlogische Geschichte. Entweder die Bedingung
tritt zu oder eben nicht. Da gibt es "wahr" und "falsch",
was -- der Bedeutung nach -- abstrakte Belegungen und
keine Zahlen sind.
Ein aussagenlogischer Ausdruck kann aber nicht sinnvoll
eine beliebige ganze Zahl als Argument haben.
Der Vergleich "(errno!=0)" löst das Problem, denn es
werden zwei Zahlen verglichen, und das Resultat ist ein
binäres Ergebnis; hier ist die Welt wieder in Ordnung.
Ich erwarte von niemandem, dass er meiner Sichtweise
folgt -- es wäre nur recht schön, wenn nicht dauernd
diese ganzen verzichtbaren Schlampigkeiten als DAS
grandiose Alleinstellungsmerkmal von C angepriesen
würden.
> Deutlich wird es auch bei "if(3>4)" da schreibt> auch niemand "if((3>4)!=0)".
???
Muss ja auch nicht: "3" ist eine Zahl, "4" ist eine
Zahl, ">" ist ein Vergleichsoperator, der ein binäres
Ergebnis liefert. Alles paletti.
Egon D. schrieb:> Ich finde umgekehrt "if (errno)" in sich widersprüchlich.
Ich lese das als: "wenn ein Fehlercode geliefert wurde, dann ...".
Deswegen benutzt man auch oft die 0 für den Erfolg.
A. S. schrieb:> Deutlich wird es auch bei "if(3>4)" da schreibt auch niemand> "if((3>4)!=0)".
if((((((((((((((((((((((3>4)!=0)!=0)!=0)!=0)!=0)!=0)!=0)!=0)!=0)!=0)!=0)
!=0)!=0)!=0)!=0)!=0)!=0)!=0)!=0)!=0)!=0))
Egon D. schrieb:> Ein aussagenlogischer Ausdruck kann aber nicht sinnvoll> eine beliebige ganze Zahl als Argument haben.
Wenn du unbedingt Mathematik bemühen willst, dann betrachte es unter dem
Aspekt der Boolschen Algebra mit Bezug auf die Mengenlehre. Dann geht
das. ;-)
Stefan ⛄ F. schrieb:> Ich lese das als: "wenn ein Fehlercode geliefert wurde, dann ...".
Benennung von Variablen ist viel wichtiger, als die Bullenexkremente,
die hier diskutiert werden.
if (error) { handle_error(); }
Stefan ⛄ F. schrieb:> Darauf wollte ich hinaus. Programmiersprachen definieren> ihr eigenes Regelwerk. Die Tatsache, dass es da viele> Gemeinsamkeiten mit anderen bekannten Regelwerken gibt,> wollte keinen Entwickler dazu verleiten, die Regeln der> Sprache zu missachten.
Seit wann ist es ein Missachten von Regeln, wenn ich
eine inhaltlich widersprüchliche Ausdrucksweise wie
"if(ganzzahl)" ablehne und durch eine konsistente
wie "if(ganzzahl==referenz)" ersetze, die genauso
regelgerecht ist?
> Die meisten Softwareentwickler benutzen regelmäßig> viele unterschiedliche Programmiersprachen mit> unterschiedlichen Regeln.
Es geht nicht um unterschiedliche Regeln -- es geht
um in sich widersprüchliche Konstrukte, für die es
widerspruchsfreie Alternativen in der Sprache gibt!
Stefan ⛄ F. schrieb:> Teo D. schrieb:>>> C ist nun einmal nicht Mathe, sonder C.>> Wer kennt ne Sprache wo das anders is?>> Darauf wollte ich hinaus. Programmiersprachen definieren ihr eigenes> Regelwerk.
Aber ich bekomme doch keinen Konten im Hirn, wegen "if(x)".
> Die Tatsache, dass es da viele Gemeinsamkeiten mit anderen> bekannten Regelwerken gibt, wollte keinen Entwickler dazu verleiten, die> Regeln der Sprache zu missachten.
Naja, das "missachten" funktioniert so oder so nich.
Stefan ⛄ F. schrieb:> ist kein Softwareentwickler.
Hab ich auch nie behautet.
Mach ich seit >30J nich mehr und wirkliche Erfahrung hatte ich nur in
einer Sprache, mit einem sehr speziellem Dialekt. :)
Also Asche auf mein Haupt, wegen obiger Frage, wo das anders wäre.
(Interessieren würds mich aber trotzdem)
Egon D. schrieb:>> und haben mit Zahlen nix am Hut.>> Das wäre schön und logisch -- ist aber in C nicht so.
Hab ich doch auch nie behautet.....
Eine Meinung, zwei Stuhle... Lassen wirs lieber!
Ich wollts doch nur einfacher... Das ging dann wohl nach Hinten los. :´D
Egon D. schrieb:> wenn ich> eine inhaltlich widersprüchliche Ausdrucksweise wie> "if(ganzzahl)" ablehne und durch eine konsistente> wie "if(ganzzahl==referenz)" ersetze
Ich werfe if (0 == variable) in den Ring.
Stefan ⛄ F. schrieb:>>> ">" ist ein Vergleichsoperator, der ein binäres>>> Ergebnis liefert.>> MaWin schrieb:>> nein>> Jetzt bin ich aber mal auf die Erklärung gespannt.
Ein Boolsches, dargestellt als 0/1.
Taugt Euch das?
>> ">" ist ein Vergleichsoperator, der ein binäres>> Ergebnis liefert.
MaWin schrieb:
> nein>> Jetzt bin ich aber mal auf die Erklärung gespannt.
MaWin schrieb:
> Lies den Thread. Es liefert ein komplettes int zurück.
"The result of a relational expression is 1 if the tested relationship
is true and 0 if it is false. The type of the result is int."
https://docs.microsoft.com/en-us/cpp/c-language/c-relational-and-equality-operators?view=msvc-160
"Ein Binärcode ist ein Code, in dem Informationen durch Sequenzen von
zwei verschiedenen Symbolen (zum Beispiel 1/0 oder wahr/falsch)
dargestellt werden."
https://de.wikipedia.org/wiki/Bin%C3%A4rcode
Da das Ergebnis nur 0 oder 1 sein kann, also zwei mögliche Werte, ist
es binär.
Stefan ⛄ F. schrieb:> Da das Ergebnis nur 0 oder 1 sein kann, also zwei mögliche Werte, ist> es binär.
Ja gut. Du hast die Sprachdefinition gefunden, die dir recht gibt. Du
hast gewonnen. Bravo.
MaWin schrieb:> Ja gut. Du hast die Sprachdefinition gefunden, die dir recht gibt. Du> hast gewonnen. Bravo.
Es wäre auch binär, wenn das Ergebnis nur die Werte 7 und 8 haben kann.
Oder "HIGH" und "LOW" oder 0V und 5V, um mal bei etwas Bekanntem zu
bleiben.
Ich erinnere mich ganz vage an die Fortran-Grundkurse, wo man einige
Jobs fürs Rechenzentrum "gewann", wenn die Abschlußklausur mindestens 2+
war. Und ich erinnere mich an den "wahnsinnigen Geheimtip", einem
Ausdruck, der einen Wahrheitswert verarbeiten will, ein numerisches
Rechenergebnis "unterzujubeln", weil eben False = 0 und True != False...
Kam mir rein vom Gefühl immer unsauber vor. Aber später, bei den ersten
Controllern war das fast schon üblich und hat auch keinen wirklich
gekratzt, solange es funzte... Trotzdem, für mich "unsauber" (was aber
nicht heißt, dass ich es nicht auch mal mache :-)
Gruß Rainer
Stefan ⛄ F. schrieb:> Es wäre auch binär, wenn das Ergebnis nur die Werte 7 und 8 haben kann.> Oder "HIGH" und "LOW" oder 0V und 5V, um mal bei etwas Bekanntem zu> bleiben.
Also war deine Aussage eine Nullaussage, weil alles auf Computern binär
ist?
Stefan ⛄ F. schrieb:> Egon D. schrieb:>> Ich finde umgekehrt "if (errno)" in sich widersprüchlich.>> Ich lese das als: "wenn ein Fehlercode geliefert wurde, dann ...".> Deswegen benutzt man auch oft die 0 für den Erfolg.
errno ist generell ein schlechtes Beispiel, weil das nicht benutzt
werden kann, um zu erkennen, ob ein Fehler aufgetreten ist. Die
Funktionen geben normalerweise über den Returnwert oder so zu erkennen,
ob ein Fehler aufgetreten ist, und nur wenn es einen gab, dann kann man
per errno abfragen, welcher Fehler das war.
Es ist nicht mal definiert, ob es überhaupt geschrieben wird, wenn kein
Fehler aufgetreten ist. Der Standard sagt sogar ausdrücklich, dass errno
von Standard-Funktionen niemals auf 0 gesetzt wird.
Die Sprache C zwingt niemanden dazu eine Zahl mit true oder false zu
vergleichen, wie
1
interrno=3;
2
if(errno==true)...
Niemand wird gezwungen, nicht boolesche Ausdrücke in if() zu benutzen,
wie in
1
interrno=3;
2
if(errno)...
Manche Programmiersprachen verbieten beides sogar. C erlaubt es halt.
Genieße die Freiheit ohne sie zu missbrauchen.
Wenn man das aber nun trotzdem macht und dabei einen Knoten im Kopf
bekommt, dann hat man sich selbst verascht. Wer dem Design der
Programmiersprache anlastet, soll erstmal selbst eine bessere
Programmiersprache auf den Markt bringen, um wenigstens ungefähr auf
Sichtweite (Augenhöhe verlange ich nicht) zu kommen.
C ist keine Sprache für Leute, die Pampers und Hosenträger brauchen. Für
diese Leute gibt es andere Programmiersprachen und Berufe/Hobbies, wo
man gar nicht programmieren muss.
>> Es wäre auch binär, wenn das Ergebnis nur die Werte 7 und 8 haben kann.>> Oder "HIGH" und "LOW" oder 0V und 5V, um mal bei etwas Bekanntem zu>> bleiben.MaWin schrieb:> Also war deine Aussage eine Nullaussage, weil alles auf Computern binär> ist?
Nein. Eine Funktion, die viele (mehr als 2) unterschiedliche
Status-Codes zurückliefert, liefert kein binäres Ergebnis zurück. Alles
was mehr als zwei Werte haben kann, ist nicht binär. Ein Byte zum
Beispiel.
Aber wenn ich einen int oder String zurückliefere und dessen gültige
Werte auf genau zwei beschränke, dann ist das binär.
Teo D. schrieb:> Nö, das sind und bleiben Boolsche Ausdrücke und haben mit Zahlen nix am> Hut. Nur Wahr oder Falsch, lässt sich halt nur recht schlecht ins RAM> tackern!
Ich wiederhole es gerne noch öfter:
In C liefern logische Ausdrücke eine ganze Zahl, nämlich 0 oder 1.
Da kann man nicht behaupten, daß sie nichts mit Zahlen zu tun hätten.
Steht so im K&R, siehe die Bilder oben.
Klaus W. schrieb:> Da kann man nicht behaupten, daß sie nichts mit Zahlen zu tun hätten.
Hat das wer gesagt? Es wurde nur gesagt, dass diese Integer-zahl binär
sei, weil sie nur zwei Werte haben kann/darf.
Stefan ⛄ F. schrieb:> C ist keine Sprache für Leute, die Pampers und Hosenträger brauchen.
Das "Argument" kommt immer wieder gerne, wenn C kritisiert wird.
Spoiler: Es ist kein Argument.
errno ist eine wohldefinierte und reservierte Variable des
C-Runtime-Systems. Diese selbst zu definieren führt zu Konflikten.
Rolf M. schrieb:> errno ist generell ein schlechtes Beispiel, weil das nicht benutzt> werden kann, um zu erkennen, ob ein Fehler aufgetreten ist.
Korrekt. errno sollte man nur abfragen, wenn man zuvor den Return-Wert
einer libc-Funktion als Fehler detektiert - vorher nicht. Denn errno
wird nie zurückgesetzt, kann also noch einen uralten Fehler beinhalten,
der längst nicht mehr aktuell ist.
Beispiel:
1
#include<errno.h>
2
...
3
FILE*fp=fopen("/tmp/a.txt","r");
4
5
if(!fp)
6
{
7
fprintf(stderr,"cannot open /tmp/a.txt, errno = %d\n",errno);
8
}
Besser:
1
#include<errno.h>
2
...
3
FILE*fp=fopen("/tmp/a.txt","r");
4
5
if(!fp)
6
{
7
perror("/tmp/a.txt");
8
}
perror wertet die Variable errno aus und schreibt dann den Grund des
Fehlers auf stderr, z.B.
MaWin schrieb:>> C ist keine Sprache für Leute, die Pampers und Hosenträger brauchen.> Das "Argument" kommt immer wieder gerne, wenn C kritisiert wird.> Spoiler: Es ist kein Argument.
Was ist es denn, ein Fakt?
Klar darfst du die Sprache ätzend finden, tue ich auch. Dennoch arbeite
ich damit.
Frank M. schrieb:> errno ist eine wohldefinierte und reservierte Variable des> C-Runtime-Systems. Diese selbst zu definieren führt zu Konflikten.
Ich wollte nur unmissverständlich klar stellen, dass es ein Integer ist,
kein boolean.
Stefan ⛄ F. schrieb:> Alles> was mehr als zwei Werte haben kann, ist nicht binär. Ein Byte zum> Beispiel.
Also gibt es gar keine binären Werte auf gängigen CPUs.
Stefan ⛄ F. schrieb:> Klaus W. schrieb:>> Da kann man nicht behaupten, daß sie nichts mit Zahlen zu tun hätten.>> Hat das wer gesagt? Es wurde nur gesagt, dass diese Integer-zahl binär> sei, weil sie nur zwei Werte haben kann/darf.
Er war's (sie war's, sie war's...):
Teo D. schrieb:> Nö, das sind und bleiben Boolsche Ausdrücke und haben mit Zahlen nix am> Hut.
MaWin schrieb:> Also gibt es gar keine binären Werte auf gängigen CPUs.
Statusbits in der CPU.
(Gleich kommt c-hater unter dne Steinen vor: ich hab's schon immer
gewusst...)
Stefan ⛄ F. schrieb:> Was ist es denn, ein Fakt?
Um das zu verstehen, muss man verstehen, dass es gar keine guten
C-Programmierer gibt.
Oder woher kommen ständig diese Sicherheitslücken, die auf trivialen
C-Eigenschaften beruhen? Alles Trottel? Außer ich? Ich bin der
Super-C-Programmierer, und alle anderen sind dumm? Wohl kaum.
MaWin schrieb:> Oder woher kommen ständig diese Sicherheitslücken, die auf trivialen> C-Eigenschaften beruhen?
Ja, vor 20 Jahren las man desöfteren davon. Buffer-Overflows waren die
bekanntesten.
Aber:
So wie ich die Meldungen von Sicherheitslücken der letzten 10 Jahre
wahrgenommen habe, beruhen mittlerweile die wenigsten Sicherheitslücken
"auf trivialen C-Eigenschaften". Da hat sich die "Qualität" mittlerweile
verschoben.
Frank M. schrieb:> von Sicherheitslücken der letzten 10 Jahre> wahrgenommen habe, beruhen mittlerweile die wenigsten Sicherheitslücken> "auf trivialen C-Eigenschaften"
Da gibt natürlich jetzt mehrere Antworten drauf:
- Ist das denn so, oder ist es nur eine falsche Wahrnehmung?
- Wenn es so ist, ist es, weil C-Programme endlich gut sind, oder weil
niemand mehr neue securitykritische SW in C schreibt (lies: Weniger
securitykritische SW in C geschrieben wird).
Ich tippe auf: beides.
MaWin schrieb:> Also gibt es gar keine binären Werte auf gängigen CPUs.
Doch, zum Beispiel die Status Flags (Zero Flag).
Und außerdem alle Bit-Kombinationen, die per Definition nur zwei gültige
Zustände haben, wie eben das besagte 0/1 Pärchen.
MaWin schrieb:>> Doch, zum Beispiel die Status Flags (Zero Flag).> Die von C aus nicht verwendbar sind.
Gut, ich gebe dir noch ein Beispiel. Letzendlich eine Wiederholng der
vorherigen nur in anderer Version.
Sagen wir mal, die Funktion tuWas() liefert 9 im Erfolgsfall und 22 im
Fehlerfall zurück. Andere Rückgabewerte sind per Spezifikation
unzulässig. Dan liefert die Funktion ein binäres Ergebnis.
Binär heißt: Es gibt nur zwei erlaubte Zustände. Ganz egal, wie viele
Zustände tatsächlich physikalisch möglich sind.
Ein digitaler Arduino Eingang ist binär, denn er kennt nur HIGH und LOW.
Du kannst reich technisch unendlich viele unterschiedliche Spannungen
anlegen. Aber es gibt nur zwei gültige Bereiche, deswegen ist das binär.
"tot" oder "lebendig" ist auch binär. Es gibt keine weiteren Werte
("untot", "bewusstlos" und "scheintot" gilt hier nicht).
Stefan ⛄ F. schrieb:> Gut, ich gebe dir noch ein Beispiel.
Was genau willst du mir eigentlich erklären?
Es gibt in C ein int. Alles wird darauf promoviert, es sei den es ist
bereits größer.
Warum spielt dein theoretisches Gedankenspiel mit 9 und 22 als binäre
Werte irgendeine Rolle in diesem Thread?
MaWin schrieb:> Was genau willst du mir eigentlich erklären?
Das es binäre (Rückgabe-)werte vom Typ int gibt, so wie es die Doku von
Microsoft auch klar aussagt.
Stefan ⛄ F. schrieb:> Das es binäre (Rückgabe-)werte vom Typ int gibt, so wie es die Doku von> Microsoft auch klar aussagt.
Ah ja. Und das hat jetzt welche Relevant genau?
Was ändert das an
"frage zu defines TRUE/FALSE"
?
MaWin schrieb:> Ah ja. Und das hat jetzt welche Relevant genau?
Die Diskussion hat dazu geführt, das ist die Relevanz. Du kannst ja
nochmal den ganzen Thread von Anfang an durchlesen um nachzuvollziehen,
wie deine eigenen Beiträge zu diesem Punkt hier geführt haben.
Stefan ⛄ F. schrieb:> Ich gebe auf.
Ich verstehe durchaus, was du meinst.
Aber es ist trotzdem Unsinn im C-Kontext.
Ein int ist ein int ist ein int.
Die Interpretation eines int interessiert es grundsätzlich nicht, ob der
Wert ursprünglich aus einem Vergleich stammt.
Das kommt höchstens bei der Optimierung und der as-if-Regel zum Tragen.
Aber im grundsätzlichen Sprachumfang kommt das nicht vor.
Egon D. schrieb:> Was ist an "if (errno>0)" so viel entsetzlicher als> an "if (errno)" -- außer dass es allgemeinverständlich> ist?
Für mich ist "if (errno>0)" nicht verständlicher. Für mich sind da zwei
zusätzliche Zeichen Quellcode ohne Nutzen, und jedes unnütze Zeichen
Quellcode ist für mich eines zu viel. Source is evil.
Aber ich habe schon viele Programmierer erlebt die da anderer Meinung
sind und für die, wie für Egon und Schlaumaier, "if (errno)" kryptisch
ist.
LG, Sebastian
Sebastian W. schrieb:> Für mich ist "if (errno>0)" nicht verständlicher. Für mich sind da zwei> zusätzliche Zeichen Quellcode ohne Nutzen, und jedes unnütze Zeichen> Quellcode ist für mich eines zu viel.
Mir kommt da spontan die Frage ind en Sinn, ob negative Fehlercode
absichtlich ignoriert werden und ob negative Werte überhaupt vorkommen.
Stefan ⛄ F. schrieb:> Mir kommt da spontan die Frage ind en Sinn, ob negative Fehlercode> absichtlich ignoriert werden und ob negative Werte überhaupt vorkommen.
Nicht fragen, sondern einfach errno.h bzw. dessen Sub-Includes
anschauen, unter Linux meist /usr/include/newlib/sys/errno.h
Ergebnis: errno ist 0 oder positiv.
Wie aber einige oben schon mehrfach(!) geschrieben haben, ist die
Prüfung mittels if(errno) Unsinn. Von daher ist es als Anwender von
errno.h auch völlig irrelevant, welche konkreten numerischen Werte errno
ungleich 0 annehmen kann. Du kannst natürlich errno auf konkrete Werte
wie ENOENT abchecken - oder aber einfach perror() aufrufen, um Dir die
konkretete Fehlermeldung ausgeben zu lassen.
errno ungleich 0 ist kein Kriterium, dass der letzte
libc-Funktionsaufruf in die Binsen ging!
Siehe auch: https://man7.org/linux/man-pages/man3/errno.3.html
Titel: errno - number of last error
Betonung liegt hier auf "last".
Auszug:
"The value of errno is never set to zero by any system call or library
function."
Frank M. schrieb:> Stefan ⛄ F. schrieb:>> Mir kommt da spontan die Frage ind en Sinn, ob negative Fehlercode>> absichtlich ignoriert werden und ob negative Werte überhaupt vorkommen.>> Nicht fragen, sondern einfach errno.h bzw. dessen Sub-Includes> anschauen, unter Linux meist /usr/include/newlib/sys/errno.h>> Ergebnis: errno ist 0 oder positiv.
Außer innen im Linux Kernel, da gibt eine Funktion ggf. -ENOENT zurück.
> errno ungleich 0 ist kein Kriterium, dass der letzte> libc-Funktionsaufruf in die Binsen ging!
Wenn man errno nicht selber auf 0 setzt, ist es meistens != 0. Zum
Beispiel sucht eine Funktion nach einer config-Datei und findet sie
nicht gleich im ersten Verzeichnis. Am Ende war alles erfolgreich, aber
errno == ENOENT.
Stefan ⛄ F. schrieb:> Vermutlich ist das zu simpel, um von einigen hier akzeptiert zu werden.
Du vergißt immer wieder das Eine: Daß es in C keinen Datentyp "boolean"
gibt und daß daraus folgt, daß es dafür einen Ersatz geben muß, denn
ohne Ergebnisse wie true oder false kommt keine Programmiersprache aus -
auch wenn sich das 'nur' in den Ergebnissen von Vergleichsoperationen
widerspiegelt.
W.S.
He Leute, mal ehrlich, wie lange wollen wir hier noch weitermachen?? Ich
bin mir sicher, dass das hier Geschriebene und Gelesene bei "0 Null Nill
Nada ect." irgend etwas an seinen Programmiergewohnheiten ändern wird!
Was zählt ist doch letztlich nur das (positive) Ergebnis. Oder hat sich
einer schon mal die fiktive Situation vorgestellt, wo "Ardunio-Fanboy"
und "C-hater" beim Chef sitzen und dem erzählen, dass,
wenn,"Ardunio-Fanboy" nicht sofort aufhört, die Integerzahl 42 als
boolsche Variable "True" zu benutzen, er, C-hater, für das Gelingen, vor
allem für das rechtzeitige Gelingen der Projektentwicklung nicht
garantieren könne. Nun kennt jeder doch diese Cartoons, wo irgendwer in
die Luft springt, explodiert...was auch immer.... Genau das wird auch im
fiktiven Chefzimmer passieren. Ein atomexplosionsähnliches Raus! ist das
Resultat. Und zu Recht!
Am Rande, und nur für mich... habe wenige Male an einer Software
"rummachen" müssen/sollen, die ich nicht selbst verbrochen hatte und ich
habe ausnahmslos die verlangte Funktionalität studiert und dann das
Kunstwerk neu geschrieben. Kann man eigentlich fast immer
durchsetzen...es sei denn "hardcoregeschütze" wie Kündigung nehmen Raum
:-)
Gruß Rainer
Stefan ⛄ F. schrieb:> Darauf wollte ich hinaus. Programmiersprachen definieren ihr eigenes> Regelwerk. Die Tatsache, dass es da viele Gemeinsamkeiten mit anderen> bekannten Regelwerken gibt, wollte keinen Entwickler dazu verleiten, die> Regeln der Sprache zu missachten.
So herum will das aber kein Mensch mit wenigstens einem Rest an
Selbstgefühl akzeptieren.
Sieh das mal anders herum:
Der Daseinszweck von Programmiersprachen besteht darin, den Willen des
Menschen in so einer Form darzustellen, daß daraus eine
Maschinenbefehlsfolge für ein entsprechendes elektronisches Ding
entstehen kann, so daß dieses Ding so funktioniert, wie es sich der
Mensch gedacht hat.
Also die Maschine soll dem Menschen dienen und nicht umgekehrt.
Die Programiersprache soll dabei nicht 'ihre' Regeln aufstellen, sondern
so gut es geht, den Regeln des Menschen entsprechen, was je nach
Programmiersparte unterschiedlich eng aufgefaßt wird. Für Leute ohne
naturwissnschaftlichen Hintergrund (wie z.B. BWLler) hat das
erwiesenermaßen in so etwas wie COBOL gemündet, alle anderen haben dafür
zu viel mathematischen Hintergrund, weswegen denen so etwas wie if(A==B)
unsinnig ist, genau so, als wenn eine Programmiersprache als 'ihre'
Regel definieren würde, daß bei ihr 1+1 = 3 und 1+1+1 = 7 wäre. Man kann
selbsternannte Regeln zwar formulieren, aber je weiter man sich damit
von der Mathematik entfernt, desto problematischer wird das.
Nochwas:
MaWin polterte ein wenig über die alten Säcke in
C-Programmierer-Kreisen. Nun, wenn gerade für Mikrocontroller
ausreichend an Alternativen zur Verfügung ständen, dann wäre dies nebst
der hier geführten Diskussion gegenstandslos.
Ja, C ist schludrig konzipiert, C ist recht alt und Programmierer ohne
Bodenkontakt zur Elektronik neigen dazu, sich in immer abenteuerlichere
Konstrukte auch beim Erfinden neuer Programmiersprachen zu versteigen.
Schließlich ist es denen gar zu oft ein inneres Bedürfnis, in 'ihrer'
Programmiersprache eine Art eigenes Reich zu haben, zu dem Außenstehende
möglichst keinen Zugang haben sollen.
Man kann in C auch lesbar und ohne Quellcode-Akrobatik, also quasi
'bieder' schreiben und das Ergebnis wird den C-Akrobaten nicht
nachstehen.
Soviel zu der Ansicht, daß sich der Verstand des Menschen (ungeprüft) an
die Regeln einer Programmiersprache zu halten habe.
W.S.
Rainer V. schrieb:> Oder hat sich> einer schon mal die fiktive Situation vorgestellt, wo "Ardunio-Fanboy"> und "C-hater" beim Chef sitzen und dem erzählen, dass,> wenn,"Ardunio-Fanboy" nicht sofort aufhört, die Integerzahl 42 als> boolsche Variable "True" zu benutzen, er, C-hater, für das Gelingen, vor> allem für das rechtzeitige Gelingen der Projektentwicklung nicht> garantieren könne.
Die Situation wird nie so geschehen!
Gar nicht so sehr, weil ich und C-hater niemals vor einem gemeinsamen
Chef auftauchen könnten.
Sondern:
Das einhalten einer Firmenphilosophie, ist mehr oder weniger einer der
Bedingungen, zugehörig zum Arbeitsvertrag. Wenn ich damit nicht
einverstanden bin, mich nicht anpassen kann, dann darf ich da nicht
arbeiten.
Was der C-hater dann tut, ist sein Problem.
Es wird also keine Welle geben.
Hallo,
W.S. schrieb:> Ja, C ist schludrig konzipiert...
Kann man so sehen.
Ich würde eher sagen das C pragmatisch konzipiert wurde, nämlich in
Hinblick auf das Programmieren von Hardware-Systemen, für die es zur
dieser Zeit scheinbar keine andere geeignete Programmiersprache gab.
Interessanterweise scheinen die nicht schludrig konzipierten Sprachen
keine Alternative gewesen zu sein.
Übrigens: gibt es überhaupt nicht schludrig konzipierte Sprachen, die
eine nennenswerte Verbreitung erlangt haben?
> Nun, wenn gerade für Mikrocontroller ausreichend an Alternativen zur> Verfügung ständen...
Da stellt sich doch direkt die Frage, warum nicht ausreichend
Alternativen
zur Verfügung stehen.
Offensichtlich muss C doch über Eigenschaften verfügen, die es trotz
aller Unzulänglichkeiten so attraktiv macht, das die Sprache auch nach
50 Jahren immer noch so weit verbreitet ist.
rhf
Roland F. schrieb:> Interessanterweise scheinen die nicht schludrig konzipierten Sprachen> keine Alternative gewesen zu sein.
Unix war für kleinere Rechner konzipiert als Multics. Nicht nur das
Betriebssystem musste dementsprechend kleiner sein, sondern auch der
genutzte Compiler.
Roland F. schrieb:> Übrigens: gibt es überhaupt nicht schludrig konzipierte> Sprachen, die eine nennenswerte Verbreitung erlangt> haben?
"Hatten": Algol? Pascal?
"Haben": C++?
> Da stellt sich doch direkt die Frage, warum nicht> ausreichend Alternativen zur Verfügung stehen.
Pfadabhängigkeit.
Eine bessere Lösung muss nicht nur in der Zukunft einen
Gewinn gegenüber der bisherigen versprechen -- sie muss
auch den Umstellungsaufwand wieder wettmachen, und der
wächst, je länger man wartet.
> Offensichtlich muss C doch über Eigenschaften verfügen,> die es trotz aller Unzulänglichkeiten so attraktiv> macht, das die Sprache auch nach 50 Jahren immer noch> so weit verbreitet ist.
Deine Lieblingsthese.
Ich halte sie für falsch.
Es ist mittlerweile sogar in der Wirtschaftswissenschaft
angekommen, dass das gebetsmühlenartig wiederholte Mantra
"Das Bessere setzt sich durch" falsch ist.
Wenn das "gerade ausreichend Gute" früh genug eine
hinreichende Verbreitung hat, setzen Mitkopplungseffekte
ein, die die Lage stabilisieren. Alternativen -- selbst
wenn sie tatsächlich besser sind -- haben es im Laufe der
Zeit schwerer und schwerer.
Arduino Fanboy D. schrieb:> Die Situation wird nie so geschehen!
Ja ja, du hast die fiktive Situation aber nicht verstanden. Jetzt bin
ich mal Chef (Werner is König und auf nach Flachköpper) und sage
schlicht: Ihr Vögel könnt von mir aus machen was ihr wollt, aber macht
es!!!
Capito?!
Gruß Rainer
Roland F. schrieb:> Übrigens: gibt es überhaupt nicht schludrig konzipierte Sprachen, die> eine nennenswerte Verbreitung erlangt haben?
Anders herum: PHP ist extrem schluderig gestaltet und dennoch eine der
erfolgreichsten Programmiersprachen geworden.
Egon D. schrieb:> "Haben": C++?
Ich mag C++, aber sauber gestaltet ist anders. Die Mehrdeutigkeit von
"static" und dass man den Shift-Operator "<<" zur Textausgabe und sogar
zu dessen Formatierung missbraucht hat ist schon sehr schluderig.
Stefan ⛄ F. schrieb:> Anders herum: PHP ist extrem schluderig gestaltet und dennoch eine der> erfolgreichsten Programmiersprachen geworden.
Wobei die Tage von PHP eindeutig gezählt sind.
Niemand setzt mehr neue Projekte mit PHP auf. Das sind alles Altlasten,
die es zu beseitigen gilt.
>> gibt es überhaupt nicht schludrig konzipierte Sprachen, die>> eine nennenswerte Verbreitung erlangt haben?Egon D. schrieb:> "Haben": C++?
Ich mag C++. Aber wenn ich an die Mehrdeutigkeit von "static" denke und
an den Missbrauch des Shift Operators nicht nur zur Textausgabe sondern
auch zu dessen Formatierung, fällt mir alles andere ein, als Lobeshymnen
auf die Klarheit/Sauberkeit der Sprache. Auch die Unterstützung von
Unicode wirkt eher wie ein nachträglich angeklebter Pickel.
Roland F. schrieb:> Übrigens: gibt es überhaupt nicht schludrig konzipierte Sprachen, die> eine nennenswerte Verbreitung erlangt haben?
Python, Rust, Go, Lua.
Ja, jede Sprache hat Ecken und Kanten.
Aber C besteht aus Ecken und Kanten, die mit Duct-Tape zusammengeklebt
wurden.
MaWin schrieb:> Roland F. schrieb:>> Übrigens: gibt es überhaupt nicht schludrig konzipierte Sprachen, die>> eine nennenswerte Verbreitung erlangt haben?>> Python, Rust, Go, Lua.
Python? Ernsthaft? Die Sprache hat allerhand halbgaren BS, auch
abgesehen von der Abstandssache. Dinge, worüber ich immer mal wieder
stolpere:
Kein block scope, keine expliziten Variablendeklarationen:
1
#!python3
2
defsomething_list_pets(self,name):
3
pets=user_pet_list[name]
4
print("You have the following pets: ")
5
forname,speciesinpets:
6
print(f" - Your beloved {species}{name}")
7
print(f"Have a nice day, {name}")
Das Letzte print gibt nicht etwa den Benutzernamen aus, sondern wurde in
der Schleife überschrieben...
Und dann gibt es dinge wie z.B. die set syntax, die sich mit der dict
syntax überschneidet: {1,2,3} ist ein set. {1} auch. {} ist aber ein
dict...
Bei async generators gibt es auch gewisse quirks. Ich sag nur aclose. Um
den quark muss man sich bei JS nicht kümmern.
Dann die Sache mit den tuple, wo man keine klammern braucht. "x=y"
"x=y," und "x,=y" sind gültig, aber anders als ersteres erstellen /
entpacken die Dinger tuple. Geht auch innerhalb von for in schleifen und
anderem zeug. Klar, bei mehreren Werten oft schön anzusehen, aber
trotzdem irgendwie Murks. Viel zu einfach, mal ein Komma zu vergessen,
oder zu übersehen.
Und das ist nur die Spitze des Eisbergs. Da gibt es noch einiges mehr an
Fallstricken.
PS: Gibt es hier im Forum eigentlich eine Möglichkeit im code tag direkt
anzugeben, das etwas z.B. python code ist? Also etwas, was nicht wie #!
mit dem code mit angezeigt wird?
Daniel A. schrieb:> Python? Ernsthaft?
Ja. Ernsthaft.
Die von dir geschilderten "Probleme" sind alle in der Praxis nicht
besonders relevant.
Bei C ist das anders. Mit UB kämpft man ständig, um mal nur ein Beispiel
zu nennen.
MaWin schrieb:> Die von dir geschilderten "Probleme"
Um das nochmal deutlicher zu sagen: Ich bin der Meinung, dass die
meisten deiner Beispiele gar keine Probleme sind.
Nicht alles, was von deiner C-Gewohnheit abweicht, ist ein Problem.
MaWin schrieb:> Daniel A. schrieb:>> Python? Ernsthaft?>> Ja. Ernsthaft.> Die von dir geschilderten "Probleme" sind alle in der Praxis nicht> besonders relevant.
Doch, die haben mir, ganz in der Praxis, schon ein paar mal den Tag
versaut. Da vergisst man dann mal ein Komma, und schon hat man den
Datensalat...
> Bei C ist das anders. Mit UB kämpft man ständig, um mal nur ein Beispiel> zu nennen.
Na du vielleicht. Passiert mir mittlerweile eigentlich nicht mehr, das
ich da rein laufen würde.
Hallo,
Egon D. schrieb:> "Hatten": Algol? Pascal?> "Haben": C++?
Algol:
Hauptverbreitungszeit zwischen (grob) 1960-1970, danach ausgestorben.
Gab es überhaupt Softwareprojekte außerhalb der universitären Blase, die
damit entwickelt wurden?
Pascal:
Wurde zeitgleich zeitgleich mit C entwickelt und hat sich trotz
ähnlicher Kompaktheit, ähnlich geringer Komplexität und deutlich
besserer theroretischer Basis nicht behaupten können. Erst als mit Turbo
Pascal eine pragmatische Version zur Verfügung stand, erweiterte sich
das Verbreitungsgebiet für circa 20. Heute gehört Pascal zu den
bedrohten Arten.
C++:
Mag sein, aber dem steht eine überbordende Vielfalt an sprachlichen
Ausdrucksmitteln gegenüber. Ob die dann (und in ihrem Zusammenwirken
untereinander) wirklich alle "nicht schludrig" entworfen wurden kann ich
zwar nicht beurteilen, habe aber bei der Komplexität von C++ gewisse
Zweifel.
> Eine bessere Lösung muss nicht nur in der Zukunft einen> Gewinn gegenüber der bisherigen versprechen -- sie muss> auch den Umstellungsaufwand wieder wettmachen, und der> wächst, je länger man wartet.
Ich wiederhole mich: C und Pascal wurden zur gleichen Zeit entwickelt,
da gab es noch keinen Umstellungsaufwand. Beide Sprachen verursachten in
etwa die gleichen "Hardwarekosten".
Warum hat sich C gegenüber Pascal durch gesetzt, obwohl doch Pascal die
bessere Basis darstellte?
> Wenn das "gerade ausreichend Gute" früh genug eine> hinreichende Verbreitung hat,...
Trifft aber bei C und Pascal, wie oben beschrieben, nicht zu.
rhf
Daniel A. schrieb:> Da vergisst man dann mal ein Komma, und schon hat man den> Datensalat
In welcher Sprache bekommt man keinen Datensalat, wenn man irgendwelche
Zeichen "vergisst"?
10, 100, 1000 alles gleich. Die Sprache muss raten, was ich will. Sind
ja nur Nullen!
Roland F. schrieb:> Warum hat sich C gegenüber Pascal durch gesetzt, obwohl doch Pascal die> bessere Basis darstellte?
Unix.
Die Qualität der Sprache war es nicht so sehr. Sondern die
Verfügbarkeit.
Ungefähr dem Zeitpunkt, als zunehmend Maschinen für selbstgehostete
Compiler wirklich geeignet und erforderlich waren, gab es auch bald C
Compiler dafür. Dafür war nicht zuletzt Johnsons Portable C Compiler
verantwortlich, ein konzeptioneller Vorläufer des GCC, der mit
überschaubarem Aufwand auf viele Zielarchitekturen umgestellt werden
konnte.
Egon D. schrieb:>> Offensichtlich muss C doch über Eigenschaften verfügen,>> die es trotz aller Unzulänglichkeiten so attraktiv>> macht, das die Sprache auch nach 50 Jahren immer noch>> so weit verbreitet ist.>> Deine Lieblingsthese.> Ich halte sie für falsch.>> Es ist mittlerweile sogar in der Wirtschaftswissenschaft> angekommen, dass das gebetsmühlenartig wiederholte Mantra> "Das Bessere setzt sich durch" falsch ist.
Die These "Das Bessere setzt sich durch" ist IMHO schon richtig, aber
mit einigen Einschränkungen:
- Die Verbesserung muss von der Mehrheit als solche wahrgenommen werden,
da spielen aber oft subjektive Aspekte eine Rolle.
- Die Verbesserung darf nicht mit deutlicher wahrgenommenen
Verschlechterungen an anderer Stelle einhergehen.
- Das Delta der wahrgenommenen Verbesserung muss einen gewissen
Schwellwert überschreiten, sonst siegt die Gewohnheit.
Des Weiteren muss berücksichtigt werden, dass je nach Produkttyp
verschiedene Formen der Verbesserung unterschiedlich bewertet werden. So
spielen bspw. bei Klamotten und teilweise auch bei Autos Verbesserungen
im Aussehen eine große Rolle, während bei Werkzeugen (zu denen auch
Programmiersprachen gehören) der praktische Nutzen höher bewertet wird.
Konkret auf Programmiersprachen bezogen bedeutet das: Der Programmierer
muss das Gefühl haben, dass er
- mit der neuen Sprache Zeit einspart (auch unter Berücksichtigung des
durch die Umstellung entstehenden Overheads) oder
- damit Dinge realisieren kann, die mit der bisherigen Sprache nicht
(oder nur mit ganz krummen Tricks) möglich sind.
Ob die Sprache schludrig konzipiert ist oder nicht, spielt dabei eine
untergeordnete Rolle, zumal dies ohnehin z.T. im Auge des Betrachters
liegt.
Es gibt ja durchaus Fälle, wo etablierte Programmiersprachen durch
neuere weitgehend verdrängt wurden. Typische Fortran-Anwendungen
(lineare Algebra, Numerik u.ä.) werden heute vermehrt in C oder C++
realisiert. Im Finanzwesen, wo früher Cobol vorherrschte, sind heute
m.W. Python und Java angesagt. Wobei man sich jetzt natürlich darüber
streiten kann, ob C++ wirklich besser als Fortran und Python wirklich
besser als Cobol ist.
Yalu X. schrieb:> Die These "Das Bessere setzt sich durch" ist IMHO schon richtig, aber> mit einigen Einschränkungen:
Es gibt eine Zeit, in der Varianten angenommen werden. Hat sich etwas
auf breiter Front durchgesetzt, gewinnt die Masse. Wirklich Neues hat es
danach schwer, auch wenn eindeutig besser - unmöglich ist es aber nicht.
Es ist aber kein Zufall, dass mit der Zeit recht viele Sprachen
entstanden sind, die mindestens einen Teil des C Sektors übernehmen
wollen oder es bereits teilweise haben. Nur hat das den
Mikrocontroller-Sektor nicht erreicht.
(prx) A. K. schrieb:> Roland F. schrieb:>> Warum hat sich C gegenüber Pascal durch gesetzt, obwohl doch Pascal die>> bessere Basis darstellte?>> Unix.>> Die Qualität der Sprache war es nicht so sehr. Sondern die> Verfügbarkeit.
Ein anderer wesentlicher Grund war, dass Pascal von einem Lehrer als
reine Lehrsprache, C aber von Praktikern für die Praxis entwickelt
wurde. Pascal war einzig und allein dafür gemacht, den Studenten
Algorithmen zu lehren, und darin (und nur darin) war es sehr gut.
So kennt Ur-Pascal bspw. nicht einmal so etwas wie Dateinamen, was dazu
führte, dass ein Programm, das einfach nur den Inhalt einer vom Benutzer
vorgegebenen Datei auflistet, in Pascal schlicht unmöglich war.
Des Weiteren konnte man in Ur-Pascal ein Programm nicht in einzelne
Übersetzungseinheiten zerlegen, was bei größeren Softwareprojekten ein
Hindernis war.
Beide (und noch weitere) Mankos wurden bald von den Compilerherstellern
durch entsprechende Spracherweiterungen beseitigt. Allerdings kochte
dabei jeder sein eigenes Süppchen, und es entstand eine Vielzahl von
Pascal-Dialekten, ähnlich wie es auch bei Basic der Fall war. Portable
Programmierung war damit erst einmal gestorben.
Weshalb Wirth bald Modula-2 nachlegte, später Oberon. Wirths erklärtes
Prinzip, Programmiersprachen genau auf ein Anwendungsszenario
zuzuschneidern und deshalb beliebig nach Bedarf zu neu definieren, half
bei der Verbreitung nicht wirklich.
Roland F. schrieb:> Pascal:> Wurde zeitgleich zeitgleich mit C entwickelt und hat> sich trotz ähnlicher Kompaktheit, ähnlich geringer> Komplexität und deutlich besserer theroretischer> Basis nicht behaupten können.
Moment -- Du hattest von "nennenswerter Verbreitung"
gesprochen, und die war m.E. durchaus gegeben. Wer war
das -- Apple? -- die irgendwelche Systemkomponenten
in Pascal programmiert haben? Auf HP-Kisten gab es --
zu meiner Überraschung -- wohl angeblich auch einen
Pascal-Compiler.
> Erst als mit Turbo Pascal eine _pragmatische_> Version zur Verfügung stand, erweiterte sich das> Verbreitungsgebiet für circa 20 [Jahre].
Naja, zu den Hochzeiten von DOS würde ich schon von
einem erdrutschartigen Sieg sprechen...
Mit dem Niedergang von Borland-Pascal und Delphi
war dann aber auch damit Schluss...
> C++:> Mag sein, aber dem steht eine überbordende Vielfalt> an sprachlichen Ausdrucksmitteln gegenüber.
Danach war ja nicht gefragt... :)
>> Eine bessere Lösung muss nicht nur in der Zukunft>> einen Gewinn gegenüber der bisherigen versprechen>> -- sie muss auch den Umstellungsaufwand wieder>> wettmachen, und der wächst, je länger man wartet.>> Ich wiederhole mich: C und Pascal wurden zur> gleichen Zeit entwickelt, da gab es noch keinen> Umstellungsaufwand.
Stop. Pascal bringst Du jetzt ins Spiel. Ich war von
der Vorstellung ausgegangen, dass jetzt jemand die
neue Wundersprache entwickelt, die C ablösen kann und
soll.
> Beide Sprachen verursachten in etwa die gleichen> "Hardwarekosten". Warum hat sich C gegenüber Pascal> durch gesetzt, obwohl doch Pascal die bessere Basis> darstellte?
Das ist m.E. einfach:
1. Wirth hatte ganz offensichtlich kein Interesse daran,
die Standardisierung von Pascal voranzutreiben und
den Standard weiterzuentwickeln. Statt dessen hat er
sich neuen Sprachen zugewandt (Modula-2, Oberon).
Das hat zu dem bekannten Pascal-Wildwuchs geführt,
aber anders als bei C fehlte der ANSI-Gärtner, der
da mal mit der Heckenschere durchgegangen wäre.
2. Pascal ist m.E. keine wirklich bessere Sprache als C,
denn das, was Pascal (ich meine das Wirthsche Standard-
pascal) bietet, ist brauchbar -- aber es bietet,
verglichen mit C, einfach zu wenig: Zeiger existieren
nur rudimentär, Zeigerarithmetik gar nicht -- das ist
besonders fatal, weil bei Arrays auch zahlreiche
Einschränkungen existieren: Die Länge des Arrays ist
fester Bestandteil des Typs, daher gibt es keine zur
Laufzeit längenvariablen Felder, und man kann ohne
Trickserei keine Unterprogramme schreiben, die Felder
beliebiger Länge als Argument akzeptieren.
Darüberhinaus sind die I/O-Funktionen fester Bestandteil
der Sprache -- man kann Pascal also nicht "freestanding"
verwenden, wie das bei C geht. Hinderlich bei System-
programmierung.
Inwieweit es möglich ist, Pascal-Module irgenwo anders
hinzuzulinken, weiss ich nicht.
Dass es trotz starker Typisierung besser geht, zeigt
FreePascal. Da gibt es nicht nur Zeigerarithmetik wie
in C -- man darf Dank der starken Typisierung auch
Prozeduren überladen. Sehr nett.
>> Wenn das "gerade ausreichend Gute" früh genug eine>> hinreichende Verbreitung hat,...>> Trifft aber bei C und Pascal, wie oben beschrieben,> nicht zu.
Ich hatte, wie schon geschrieben, auch nicht an Pascal
gedacht.
Im übrigen teile ich die These, C sei schlampig
entworfen, gar nicht. C ist im Gegenteil ein kleines
Wunder -- auch Dank der Nachbesserungen durch die
verschiedenen Standards.
Man muss m.E. nur verstehen, dass der Fokus zur Zeit
seiner Entstehung auf komplett anderen Eigenschaften
lag, als das heute der Fall ist.
Die Sprache ist weniger das Problem -- eher die Lehr-
tradition. Es heißt ja auch nicht "Stop using C",
es heißt "Stop teaching C" :)
Roland F. schrieb:> Warum hat sich C gegenüber Pascal durch gesetzt, obwohl doch Pascal die> bessere Basis darstellte?>
Ich kann dir einen sehr handfesten Grund sagen: Pascal konnte auch ein
Cheffe lesen und so lala verstehen - C hingegen nicht, das war für ihn
wie Hieroglyphen. Sowas ändert die Ansichten im Falle einer anstehenden
Personal-Reduktion beim Cheffe. Das ist kein Argument technischer Natur,
sondern kommt aus der Personal-Politik, wiegt aber deutlich schwerer als
programmtechnische Belange.
Yalu X. schrieb:> Konkret auf Programmiersprachen bezogen bedeutet das: Der Programmierer> muss das Gefühl haben, dass er>> - mit der neuen Sprache Zeit einspart (auch unter Berücksichtigung des> durch die Umstellung entstehenden Overheads) oder>> - damit Dinge realisieren kann, die mit der bisherigen Sprache nicht> (oder nur mit ganz krummen Tricks) möglich sind.>
Nö, die schwerer wiegenden Gründe hab ich bereits weiter oben genannt.
Und nenne mir einmal ein Beipiel, wo man in C ein Ding realisieren kann,
was in heutigem Pascal nicht geht. Es ist eher umgekehrt - und zwar in
allen Belangen. Dennoch mögen gar manche Programmierer C mehr als
Pascal, die Gründe sind eigentlich immer rein geschmacklicher Natur. Ein
ehemaliger Kollege von mir meinte dazu, daß Pascal ihm zu wort- und
buchstabenreich sei, insbesondere durch 'begin' und 'end' und daß Pascal
ihm zu wenig stylisch sei im Aussehen des Quellcodes.
Tja, da kann man nix machen, gegen Geschmäcker helfen keinerlei
Argumente.
W.S.
W.S. schrieb:> Und nenne mir einmal ein Beipiel, wo man in C ein> Ding realisieren kann, was in heutigem Pascal nicht> geht.
"Programmiere eine Bibliotheksfunktion für die
Wochentagsberechnung, die sich ohne Veränderung für
MSP430, ATMega, 8052 und i386 übersetzen lässt."
Wohlgemerkt: Gemeint ist nicht "... übersetzen ließe ,
wenn ein Compiler existierte ...", sondern gemeint
ist: "... tatsächlich übersetzen lässt".
W.S. schrieb:> Ich kann dir einen sehr handfesten Grund sagen: Pascal konnte auch ein> Cheffe lesen und so lala verstehen - C hingegen nicht, das war für ihn> wie Hieroglyphen.
Musst du deinen Code tatsächlich immer deinem Chef zur Absegnung
vorlegen? ;-)
Aber mal ganz abgesehen davon: Welcher Chef, der nur wenig Ahnung von
Programmierung hat, versteht folgenden Pascal-Code, der ein Element in
eine doppelt verkettete Liste einfügt?
1
procedure realistic_insert_link( a, c: link_ptr );
2
begin
3
if a^.next <> nil then a^.next^.prev := c;
4
c^.next := a^.next;
5
a^.next := c;
6
c^.prev := a;
7
end;
Quelle:
https://rosettacode.org/wiki/Doubly-linked_list/Element_insertion#Pascal
In C würde man halt <> durch !=, ^. durch -> und := durch = ersetzen. Wo
ist da der große Unterschied bzgl. der Hieroglyphen.
Das Argument mit der Lesbarkeit durch Unerfahrene lasse ich allenfalls
für Cobol gelten. Oder doch nicht, denn auch ein nicht ganz triviales
Cobol-Programm lässt einen typischen Chef nur Bahnhof verstehen.
Nachtrag:
Dein Argument mit der Lesbarkeit von Pascal durch Chefs hinkt sowieso:
Denn dann würde ja in jeder Firma, wo der Chef auch nur ein Bisschen was
zu sagen hat, nur noch in Pascal programmiert.
Apropos Chefs und Hieroglyphen. Ein früherer Chef hatte was für APL
übrig und sich eigens IBMs APL mitsamt Umbausatz für die Tastenkappen
besorgt. Anbei eine FFT in APL.
Also unterschätzt die Chefs nicht!
Egon D. schrieb:> Es ist mittlerweile sogar in der Wirtschaftswissenschaft> angekommen, dass das gebetsmühlenartig wiederholte Mantra> "Das Bessere setzt sich durch" falsch ist.
In vielen Fällen sind die Kriterien für "das Bessere" einfach subjektiv.
Natürlich "war Apple besser", aber auch teurer, langsamer, unflexibler,
...
Natürlich "ist Pascal besser", aber auch geschwätziger, komplexer bzw.
unflexibler, ...
Daniel A. schrieb:> Das Letzte print gibt nicht etwa den Benutzernamen aus, sondern wurde in> der Schleife überschrieben...
Immerhin gewöhnt Python einem ganz schnell das Copy-Paste programmieren
ab. Man merkt schnell, dass man sich nach dem Kopieren jede einzelne
besser dreimal angucken sollte.
Roland F. schrieb:> Warum hat sich C gegenüber Pascal durch gesetzt, obwohl doch Pascal die> bessere Basis darstellte?
Ich hatte zuerst Pascal gelernt und zwei kommerzielle Projekte damit
entwickelt. Eins für DOS und eins für Windows. Die Windows Anwendung
sollte einige Windows-Spezifische Funktionen überstützen, wie
Statusmeldungen in der Taskleiste, Drag&Drop, sowie kommunikation mit
MS-Office.
Dabei war es für mich immer hinderlich, dass die Doku von Microsoft von
C ausging. Ich musste immer dolmetschen. Da ging mir irgendwann zu sehr
auf die Nerven, so kam ich freiwillig zu C und kurz danach zu C++.
Zu der Zeit programmierte ich Mikrocontroller in Assembler, später dann
logischerweise auch in C.
A. S. schrieb:> Egon D. schrieb:>> Es ist mittlerweile sogar in der Wirtschaftswissenschaft>> angekommen, dass das gebetsmühlenartig wiederholte Mantra>> "Das Bessere setzt sich durch" falsch ist.>> In vielen Fällen sind die Kriterien für "das Bessere"> einfach subjektiv.
Die Kriterien für "sich durchsetzen" aber auch. :)
Faktisch läuft auf (fast) allem außer Desktops ein
Linux-Derivat. Trotzdem spricht niemand davon, "Linux
habe sich durchgesetzt".
Und Bill Gates ist der Milliardär, nicht Linux Torvalds.
> Natürlich "ist Pascal besser",
Das bestreite ich :)
Hallo,
Yalu X. schrieb:> Ein anderer wesentlicher Grund war, dass Pascal von einem Lehrer als> reine Lehrsprache, C aber von Praktikern für die Praxis entwickelt> wurde. Pascal war einzig und allein dafür gemacht, den Studenten> Algorithmen zu lehren, und darin (und nur darin) war es sehr gut.
Genau das ist der Punkt.
Man könnte auch sagen das Pascal für Probleme entworfen wurde, die die
Mehrheit der Programmierer damals nicht hatte, während genau die
Probleme löst, die damals anstanden, nämlich die Systemprogrammierung
der neuartigen Minicomputer.
rhf
Roland F. schrieb:> Man könnte auch sagen das Pascal für Probleme entworfen> wurde, die die Mehrheit der Programmierer damals nicht> hatte, während genau die Probleme löst, die damals> anstanden, nämlich die Systemprogrammierung der> neuartigen Minicomputer.
Das greift deutlich zu kurz. Auch die Regeln des
Straßenverkehrs sind nicht ausschließlich bzw. primär
dazu entworfen, die Probleme der Autofahrer zu lösen,
sondern den Radfahrern und Fußgängern eine
Überlebenschance zu lassen.
In den 60ern und 70ern gab es den Begriff der "Software-
krise", und diese wurde u.a. darauf zurückgeführt, dass
die Softwerkerei nicht als solide ingeneurtechnischen
Disziplin mit erprobten und gesicherten Methoden
praktiziert wurde, sondern dass da im Wesentlichen ein
Haufen genialer (oder sich für genial haltender) Chaoten
am Werk war, die in brainfuck-ähnlichen Sprachen
Programme zusammengefrickelt haben, die für niemanden
außer ihnen selbst verständlich und wartbar waren.
Soll heißen: Qualitätssicherung und eine über den
Horizont des Einzelprojektes hinausgehende Arbeits-
teilung waren Fremdworte.
Dass heute nicht in fast jeder Familie ein Therac-25-
Opfer zu beklagen ist, haben wir also auch und gerade
Leuten wie Wirth zu verdanken, die versucht haben,
schon in der Lehre, in der Ausbildung künftiger
Programmierer anzusetzen.
Hallo,
Egon D. schrieb:> Moment -- Du hattest von "nennenswerter Verbreitung"> gesprochen, und die war m.E. durchaus gegeben.
Ja, das stimmt.
> Naja, zu den Hochzeiten von DOS würde ich schon von> einem erdrutschartigen Sieg sprechen...
Wovon heute nichts mehr zu sehen ist, weil...
> Mit dem Niedergang von Borland-Pascal und Delphi> war dann aber auch damit Schluss...
Merkwürdigerweise haben aber selbst freie Nachfolger/Clone wie Free
Pascal haben daran nicht mehr ändern können.
> Stop. Pascal bringst Du jetzt ins Spiel. Ich war von> der Vorstellung ausgegangen, dass jetzt jemand die> neue Wundersprache entwickelt, die C ablösen kann und> soll.
Da haben wir wohl aneinander vorbeigeredet. Mir ging es um die Frage
warum sich die Sprache mit der schlechteren Basis durchgesetzt hat.
> 1. Wirth hatte ganz offensichtlich kein Interesse daran,> die Standardisierung von Pascal voranzutreiben und> den Standard weiterzuentwickeln.
Das stimmt so nicht. Vor mir liegt das Buch "pascal, USER MANUAL AND
REPORT, THIRD EDITION ISO Pascal Standard" von Kathleen Jensen und
Niklaus Wirth, von November 1974.
> Im übrigen teile ich die These, C sei schlampig> entworfen, gar nicht. C ist im Gegenteil ein kleines> Wunder -- auch Dank der Nachbesserungen durch die> verschiedenen Standards.
Da stimme ich absolut zu.
> Man muss m.E. nur verstehen, dass der Fokus zur Zeit> seiner Entstehung auf komplett anderen Eigenschaften> lag, als das heute der Fall ist.
Das stimmt und es stimmt auch wieder nicht. Wenn man die damaligen
Minicomputer mit ihren heutigen Nachfahren vergleicht, ist das
sicherlich richtig. Aber bei der Systemprogrammierung von z.B. kleineren
Mikrocontrollern ist der Unterschied zu den alten Rechner nicht
besonders groß.
rhf
Egon D. schrieb:> .> Und Bill Gates ist der Milliardär, nicht Linux Torvalds.
Weil Bill Gates etwas geschaffen hat und nicht sein Stallbursche.
Egon D. schrieb:> Software-> krise", und diese wurde u.a. darauf zurückgeführt, dass> die Softwerkerei nicht als solide ingeneurtechnischen> Disziplin mit erprobten und gesicherten Methoden> praktiziert wurde, sondern dass da im Wesentlichen ein> Haufen genialer (oder sich für genial haltender) Chaoten> am Werk war,
Das mag man damals als Grund gesehen haben. Der Begriff bezeichnet aber
eher die Erkenntnis, dass SW teurer (und viel komplexer) ist, als HW.
Etwas völlig neues. Und daran hat sich nichts geändert. Du kannst sicher
sein, dass auch im den 50ern und 60ern programmierteams von 100 oder
1000 Leuten nicht aus Einzelkämpfern bestanden. Vielleicht im Gegenteil,
heute kann jemand alleine ein facemesh bauen und Milliardär werden.
Roland F. schrieb:>> Mit dem Niedergang von Borland-Pascal und Delphi>> war dann aber auch damit Schluss...>> Merkwürdigerweise haben aber selbst freie> Nachfolger/Clone wie Free Pascal haben daran nicht> mehr ändern können.
Naja, die Gesamtsituation ist heute anders als vor
30 Jahren. Die Rechner sind viel leistungsstärker
und es gibt viel mehr Konkurrenz durch Scriptsprachen.
Wer ein kleines Progrämmchen incl. GUI zusammennageln
will, nimmt Java oder Python/Tkinter; das ist dann,
wenn's gut läuft, auch plattformunabhängig.
> Mir ging es um die Frage warum sich die Sprache mit> der schlechteren Basis durchgesetzt hat.
Naja, woran macht Du die "schlechtere Basis" fest?
Alles, was man in (Standard-)Pascal ausdrücken kann,
kann man auch in C machen.
Darüberhinaus gehen in C aber auch noch Sachen, die
in (Standard-)Pascal nicht vernünftig machbar sind,
die der systemnahe Programmierer aber dringend
braucht.
Genannt wurden:
- I/O gehört bei Pascal zum Sprachkern; bei C steckt
das in der Standardbibliothek.
- C erlaubt "freistehenen" Betrieb (also Compilat
läuft ohne OS); das geht bei Pascal m.W. nicht.
- C kennt Pointer und Pointerarithmetik; Pascal kennt
Pointer nur rudimentär, Pointerarithmetik gar nicht
und nur Arrays mit zur Laufzeit fester Länge.
- C kann einzelne Einheiten separat übersetzen und
nachträglich zusammenlinken; das geht bei Standard-
Pascal m.W. auch nicht.
Die Grundsituation ist also fast immer: "In C geht
es mit standardkonformen Mitteln, ist aber Gewürge
und Gefrickel. In Pascal geht es mit standard-
konformen Mitteln gar nicht."
Wofür wird sich ein Programmierer, der gegen Geld
arbeitet, wohl entscheiden?
>> 1. Wirth hatte ganz offensichtlich kein Interesse>> daran, die Standardisierung von Pascal>> voranzutreiben und den Standard weiterzuentwickeln.>> Das stimmt so nicht.
Doch.
> Vor mir liegt das Buch "pascal, USER MANUAL AND> REPORT, THIRD EDITION ISO Pascal Standard" von> Kathleen Jensen und Niklaus Wirth, von November 1974.
Schön.
Und wo sind "Pascal-89", "Pascal-99", "Pascal-11"
und "Pascal++"?
Das hatte ich gemeint.
>> Man muss m.E. nur verstehen, dass der Fokus zur Zeit>> seiner Entstehung auf komplett anderen Eigenschaften>> lag, als das heute der Fall ist.>> Das stimmt und es stimmt auch wieder nicht. Wenn man> die damaligen Minicomputer mit ihren heutigen Nachfahren> vergleicht, ist das sicherlich richtig. Aber bei der> Systemprogrammierung von z.B. kleineren Mikrocontrollern> ist der Unterschied zu den alten Rechner nicht besonders> groß.
Doch!
Damals musste der C-Compiler auf einer Maschine mit 8k
Worten zu je 14 Bit laufen.
Heute wird crosscompiliert -- d.h. der Compiler läuft
auf einer Kiste mit 16GByte RAM und 3GHz Takt; nur das
Compilat -- also das übersetzte Programm! -- muss auf
dem Mikrocontroller mit 8k Flash und 1k RAM laufen.
Komplett andere Ausgangslage.
Yalu X. schrieb:> Musst du deinen Code tatsächlich immer deinem Chef zur Absegnung> vorlegen?
Nö.
Aber ich hätte da auch keine Befürchtungen.
Und: es geht hier weder um mich privat noch um dich privat. Also bleib
auch du lieber sachlich.
Zur Sache, also zum Abhaken der Diskussion zwischen C un Pascal: Pascal
war und ist nur für relativ wenige Plattformen zu bekommen. Insbesondere
nicht für alles, was man unter 'Mikrocontroller' zusamenfassen kann -
wenn man mal Mikroe beiseite läßt. Es hatte auch nie in der Zeit vor
Freepascal einen freien Compiler gegeben - und der Laufzeit-Interpreter
für Wirth's Zwischencode-Compilat war nicht gerade prickelnd. Insofern
hatte Pascal nur durch Borland (und deren Nachfahren) eine Basis - und
das war deutlich weniger als bei C. Na, vielleicht ringt sich irgendwer
mal durch, einen tatsächlich für ARM und MIPS geeigneten Compiler daraus
zu bauen. Und in der Zwischenzeit kann man auch seine Firmware in C
formulieren und dabei dennoch mit den Füßen auf dem Boden bleiben.
W.S.
A. S. schrieb:>> Und Bill Gates ist der Milliardär, nicht Linux Torvalds.>> Weil Bill Gates etwas geschaffen hat und nicht sein Stallbursche.
Direkt arm ist Torvalds aber auch nicht. Er wird auf 50 Mio taxiert.
Egon D. schrieb:> Und wo sind "Pascal-89", "Pascal-99", "Pascal-11" und "Pascal++"?
Es gibt immerhin ISO 7185:1983, ISO 7185:1990 (Standard-Pascal) und
ISO/IEC 10206:1991 (Extended Pascal), die man auch als Pascal 83, Pascal
90 und Pascal 91 bezeichnen könnte. Nach 1991 gab es allerdings keine
weiteren Normierungsbestrebungen mehr, da sich kaum noch jemand dafür
interessierte und mittlerweile mit Turbo-Pascal ein konkurrierender
De-Facto-Standard geschaffen wurde, gegen den es sich nicht anzukämpfen
lohnte.
Delphi und Free Pascal wären in dieser Nomenklatur dann Pascal++.
Yalu X. schrieb:> Egon D. schrieb:>> Und wo sind "Pascal-89", "Pascal-99", "Pascal-11" und>> "Pascal++"?>> Es gibt immerhin ISO 7185:1983, ISO 7185:1990> (Standard-Pascal) und ISO/IEC 10206:1991 (Extended Pascal),> die man auch als Pascal 83, Pascal 90 und Pascal 91> bezeichnen könnte.
Richtig.
Dem entsprechen ungefähr ANSI-C/C90.
> Nach 1991 gab es allerdings keine weiteren> Normierungsbestrebungen mehr, da sich kaum noch> jemand dafür interessierte
Eben. Das war mein Punkt.
1991 liegt dreißig (!!) Jahre zurück.
> und mittlerweile mit Turbo-Pascal ein konkurrierender> De-Facto-Standard geschaffen wurde, gegen den es sich> nicht anzukämpfen lohnte.
Ja -- "... SCHEINBAR nicht anzukämpfen lohnte".
Denn so schnell, wie DOS verschwunden war, war auch
Turbo-/Borland-Pascal wieder weg vom Fenster. Geblieben
ist die Normungslücke.
> Delphi und Free Pascal wären in dieser Nomenklatur> dann Pascal++.
... nur ohne den Hauptvorteil von C++: Den Standard.
(prx) A. K. schrieb:> A. S. schrieb:>>> Und Bill Gates ist der Milliardär, nicht Linux>>> Torvalds.>>>> Weil Bill Gates etwas geschaffen hat und nicht>> sein Stallbursche.>> Direkt arm ist Torvalds aber auch nicht. Er wird> auf 50 Mio taxiert.
Eben.
Jetzt geh' auf die Straße und frage 100 Leute, wer
sich "in der IT durchgesetzt hat". Wenn auch nur
10 Leute "Linus Torvalds" sagen, geben ich ein
Volksfest...
Egon D. schrieb:> Jetzt geh' auf die Straße und frage 100 Leute, wer> sich "in der IT durchgesetzt hat". Wenn auch nur> 10 Leute "Linus Torvalds" sagen, geben ich ein> Volksfest...
Hat Torvalds auch TRUE und FALSE definiert?
MaWin schrieb:> Egon D. schrieb:>> Jetzt geh' auf die Straße und frage 100 Leute, wer>> sich "in der IT durchgesetzt hat". Wenn auch nur>> 10 Leute "Linus Torvalds" sagen, geben ich ein>> Volksfest...>> Hat Torvalds auch TRUE und FALSE definiert?
Hat Bill Gates das getan?
Klaus W. schrieb:> In den Windows-Headerdateien wird tatsächlicxh mit TRUE und FALSE> gespielt; irgendwo dadrin ist das definiert...
Dann ist Gates wohl doch besser als Torvalds.
Daniel A. schrieb:> Kein block scope, keine expliziten Variablendeklarationen:#!python3> def something_list_pets(self, name):> pets = user_pet_list[name]> print("You have the following pets: ")> for name, species in pets:> print(f" - Your beloved {species} {name}")> print(f"Have a nice day, {name}")> Das Letzte print gibt nicht etwa den Benutzernamen aus, sondern wurde in> der Schleife überschrieben...
Was soll man dazu jetzt zu diesem Beispiel sagen? "name" nimmt in der
Schleife alle Werte in pets an und hat nach Beendigung der Schleife
natürlich den letzten Listenwert drin. Und den druckst du dann in der
letzten Anweisung aus. Und?? Ich hoffe mal, dass du wenigstens kein
C-hater bist :-)
Gruß Rainer
Felix schrieb:> Wie kommt es, dass man doch meistens die erstere variante sieht?
Ich versteh echt net, warum man da so lange rumredet...
Das ist Compiler abhängig.
" Die Größe einer _Bool-Variablen ist plattformabhängig und kann 8 Bit
übersteigen."
https://de.wikipedia.org/wiki/Datentypen_in_C#bool
Es ist bekannt, das in ASM eine Abfrage auf 0 implementiert ist,
alles andere benötigt mehr Befehle.
Wenn FALSE = 0 ist,
dann ist das TRUE != 0
Alles andere ist egal.
Somit ist es auch schneller wenn man auf 0 prüft anstatt auf >= 500ms
z.B. bei einem Timeout zu prüfen.
Ob der Complier nun wirklich im BitBang Bereich das bool anlegt oder
eine
Systemspezifische größe nimmt (für bool) z.B. uint8_t...
0 ist nun mal 0.
Rainer V. schrieb:> Was soll man dazu jetzt zu diesem Beispiel sagen? "name" nimmt in der> Schleife alle Werte in pets an und hat nach Beendigung der Schleife> natürlich den letzten Listenwert drin.
Ist mir schon klar. Der springende Punkt ist, das der Fehler einfach zu
machen, aber nur selten gewollt ist. Insbesondere, wenn man sich
Sprachen gewohnt ist, wo man variablen deklarieren kann, und es einen
ordentlichen Block Scope gibt. Bei vielen Sprachen (JS, C, C++, Rust,
Java, etc.) kann ich das, dann gewöhnt man sich an, die Loop variablen
nur im Loop zu definieren, und dann bekommt man solche Probleme im
vornherein nicht. Ich habe die Einführung von let und const in JS
erlebt. Ich garantiere dir, das vereinfacht alles extrem, was das
Ausmacht, das sind Welten!
Egon D. schrieb:> Denn so schnell, wie DOS verschwunden war, war auch> Turbo-/Borland-Pascal wieder weg vom Fenster.
Nein, es wurde erweitert (u.a. um objektorientierte Elemente) und in
Delphi umbenannt.
>> Delphi und Free Pascal wären in dieser Nomenklatur>> dann Pascal++.>> ... nur ohne den Hauptvorteil von C++: Den Standard.
Wenn es für eine Sprache nur einen relevanten Compiler gibt und einen
zweiten, der diesen einen möglichst gut nachzuahmen versucht, braucht es
keinen ISO-Standard. Der Referenzcompiler sagt einfach, wo es lang geht.
Das ist bei Python, Ruby, Tcl, Perl, Scheme, Visual Basic und vielen
weiteren Sprachen auch nicht anders.
Bei C/C++ geht so etwas natürlich nicht, weil dort ein Streit unter den
zig Compiler-Herstellern darüber losbrechen würde, welcher Compiler denn
nun von allen anderen als Referenz akzeptiert werden soll.
Egon D. schrieb:> Schön.> Und wo sind "Pascal-89", "Pascal-99", "Pascal-11"> und "Pascal++"?>> Das hatte ich gemeint.
Du ziehst Vergleiche zu Wirth's Ur-Pascal. Kann man machen, stellt aber
nur den damaligen Zustand dar und sollte dann auch mit dem
ursprünglichen K&R C verglichen werden. Vergleiche mal heutiges Pascal
mit heutigem C oder C++. Das wäre weitaus interessanter.
Abgesehen davon sind deine Schlüsse gelinde gesagt ein wenig schräg.
W.S.
Yalu X. schrieb:> Egon D. schrieb:>> Denn so schnell, wie DOS verschwunden war, war>> auch Turbo-/Borland-Pascal wieder weg vom Fenster.>> Nein, es wurde erweitert (u.a. um objektorientierte> Elemente)
Stimmt so nicht. Bereits Turbo-/Borland-Pascal brachte
OOP mit. TurboPascal mit TurboVision lief unter DOS;
Borland-Pascal gabs m.E. (auch) für Windows.
> und in Delphi umbenannt.
Sicher -- aber das war meiner Erinnerung nach ein
permanenter Kampf gegen den drohenden Untergang.
Die Idee war super, aber die Features kamen zu
spät, waren zu unausgereift und zu fehlerhaft.
>>> Delphi und Free Pascal wären in dieser Nomenklatur>>> dann Pascal++.>>>> ... nur ohne den Hauptvorteil von C++: Den Standard.>> Wenn es für eine Sprache nur einen relevanten Compiler> gibt und einen zweiten, der diesen einen möglichst gut> nachzuahmen versucht, braucht es keinen ISO-Standard.
Na, dann schau Dir mal an, wieviele Dialekte FreePascal
unterstützt (meiner Erinnerung nach sind es fünf). Das
Chaos bei den Stringtypen hat m.E. epische Ausmaße
erreicht.
Egon D. schrieb:> Bereits Turbo-/Borland-Pascal brachte> OOP mit. TurboPascal mit TurboVision lief unter DOS;> Borland-Pascal gabs m.E. (auch) für Windows.
Ja. Borland Pascal hatte bis Windows 95 Anpassungen erhalten, danach
wurde es in Delphi umbenannt.
Daniel A. schrieb:> Ist mir schon klar. Der springende Punkt ist, das der Fehler einfach zu> machen, aber nur selten gewollt ist.
Es lohnt hier nicht, das weiter zu diskutieren...ich weiß, was du sagen
willst und so einen Fehler macht als Anfänger sicher jeder mal! Viel
schlimmer finde ich an Python (das ich mir als 2te Hochsprache neben
VisualBasic unter Windoof uralt geönnt habe) dass es immer ein
Kuddelmuddel der Typen gibt. Wenn ich mit np.arrays arbeite und
Operationen ausführe, kommen manchmal als Ergebnis np.arrays raus,
manchmal aber auch effe Listen! Nun fragt sich sicher mancher, wie blöd
ich denn sein muß...ja, dann bin ich blöd und es hat mich (nicht nur in
der Lernphase) stunden gekostet, da Fehler zu finden. Denn
Fehlermeldungen vom System erzeugt das nicht! Und so geht es seinen
Gang...
Gruß Rainer
Rainer V. schrieb:> Wenn ich mit np.arrays arbeite und
Was soll das sein?
np.ndarray?
> Operationen ausführe, kommen manchmal als Ergebnis np.arrays raus,> manchmal aber auch effe Listen
Was ist eine "effe Listen"?
Kannst du bitte mal ein Beispiel geben?
Aus ndarray-Operationen kommen eigentlich ausschließlich ndarrays raus.
MaWin schrieb:> Aus ndarray-Operationen kommen eigentlich ausschließlich ndarrays raus.
Nein...aber das gehört hier jetzt nicht hin! Wenn du das noch nicht
erlebt hast, dann sei froh...und wie gesagt, vermutlich bin ich der
Depp...
Gruß Rainer
Yalu X. schrieb:> Musst du deinen Code tatsächlich immer deinem Chef zur Absegnung> vorlegen? ;-)
haben das die VW Ingenieure etwa nicht gemacht?
Irgendwie hiess es doch immer wir wussten von NICHTS.
In der Prüfgeräte Entwicklung glaubte mir mein Chef nicht mal das das
alte Programm das ich anpassen sollte für neue Baugruppen nur
Luftmessungen machte! Egal ob mit Prüfling oder Ohne es kam immer GUT
raus.
Sein Kommentar, da liefen 100k Baugrupen drüber!
W.S. schrieb:> Egon D. schrieb:>> Schön.>> Und wo sind "Pascal-89", "Pascal-99", "Pascal-11">> und "Pascal++"?>>>> Das hatte ich gemeint.>> Du ziehst Vergleiche zu Wirth's Ur-Pascal.
Naja, der "zweite revidierte Bericht" darf es schon
sein. Aber abgesehen davon -- ja, ich versuche,
Vergleichbares zu vergleichen.
> Kann man machen, stellt aber nur den damaligen> Zustand dar und sollte dann auch mit dem> ursprünglichen K&R C verglichen werden.
Naja, ich finde es sinnvoller, Standard-Pascal mit
ANSI-C zu vergleichen; das haut auch zeitlich ungefähr
hin. Die allerersten Entwürfe herzunehmen finde ich dann
doch nicht fair. Jeder hat das Recht auf Fehlgriffe...
> Vergleiche mal heutiges Pascal mit heutigem C> oder C++. Das wäre weitaus interessanter.
Finde ich nicht. Der Vergleich ist schnell zu
Ende.
Heutiges C(++): Genormt, mehrere Compiler von
mehreren Anbietern. Relativ weite Verbreitung auf
vielen Plattformen.
Heutiges Pascal: Nicht genormt, FreePascal. Ach
so: Mikroe (oder wie die heißen). Keine kommerzielle
Bedeutung.
> Abgesehen davon sind deine Schlüsse gelinde gesagt> ein wenig schräg.
Ich bin, so unglaublich es auch klingen mag, für
Veränderungen offen -- sofern gute Gründe genannt
werden. :)