Forum: Mikrocontroller und Digitale Elektronik frage zu defines TRUE/FALSE


von Felix (Gast)


Lesenswert?

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
bool x;
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?

von Wolfgang (Gast)


Lesenswert?

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.

von Wolfgang (Gast)


Lesenswert?

Ich würde allerdings
1
#define TRUE (1==1)
2
#define FALSE (!TRUE)
 bevorzugen

von A. S. (Gast)


Lesenswert?

Wolfgang schrieb:
> weil du hierbei dem Compiler keine Vorgaben machst.

Was bedeutet das?

Was ist an (0) und (1) bzw (!0) falsch?

von Wolfgang (Gast)


Lesenswert?

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.

von Wolfgang (Gast)


Lesenswert?

Und (1) ist schon mal ganz falsch, weil jeder Wert ungleich (0) gültig 
ist.

von Rolf M. (rmagnus)


Lesenswert?

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.

von Falk B. (falk)


Lesenswert?

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.

von Teo (Gast)


Lesenswert?

Wolfgang schrieb:
> Du musst Vorwissen darüber reinstecken, was dein
> Compiler/Programmiersprache als true erkennt.

C
https://openbook.rheinwerk-verlag.de/c_von_a_bis_z/005_c_basisdatentypen_015.htm#mjea5fead98f181cf7573325643e428fa3
C++
http://userpage.fu-berlin.de/~ram/pub/pub_jf47ht81Ht/c++_wahrheitswert_literale

TRUE = 1
FALSE = 0

int xy = TRUE/FALSE funktioniert also .... leider!

von Falk B. (falk)


Lesenswert?

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!

von Mark B. (markbrandis)


Lesenswert?

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
> bool x;
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.

von Rolf M. (rmagnus)


Lesenswert?

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.

von BeBe (Gast)


Lesenswert?

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.

von Stefan F. (Gast)


Lesenswert?

Ich benutze stdbool.h und vertraue darauf, dass die Entwickler des C 
Compiles (und der Bibliothek) schon wissen, was sie tun.

von Rolf M. (rmagnus)


Lesenswert?

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.

: Bearbeitet durch User
von Wolfgang (Gast)


Lesenswert?

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:
1
#define FALSE 0
2
#define TRUE 1
3
int x,y;
4
x=3;
5
if (x) 
6
  y=1;
7
if (x==TRUE)
8
  y=2;
Was erwartest du am Ende für y?

von Rolf M. (rmagnus)


Lesenswert?

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.

von Falk B. (falk)


Lesenswert?

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!

von Rolf M. (rmagnus)


Lesenswert?

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.

von Teo (Gast)


Lesenswert?

Wer mit Krücken arbeitet, muss halt humpeln. :)

TRUE/FALSE sollten keinen Zahlenwert besitzen.
bool xy = TRUE/FALSE; OK
int xy = TRUE/FALSE; Error

von Stefan F. (Gast)


Lesenswert?

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.

von MaWin (Gast)


Lesenswert?

Schon recht peinlich, was hier alles behauptet wird.
Googelt mal nach _Bool.

von P. S. (namnyef)


Lesenswert?

Schlicht und einfach:
1
#include <stdbool.h>

: Bearbeitet durch User
von Rolf M. (rmagnus)


Lesenswert?

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.

: Bearbeitet durch User
von Wolfgang (Gast)


Lesenswert?

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.

von A. S. (Gast)


Lesenswert?

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.

von Wolfgang (Gast)


Lesenswert?

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.

von Rolf M. (rmagnus)


Lesenswert?

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.

von Wolfgang (Gast)


Lesenswert?

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:
1
#define FALSE 0
2
int a,x,y;
3
4
a=!FALSE;
5
x=3;
6
7
if (x) 
8
  y=1;
9
10
if (x==a)
11
  y=2
12
}

von Rolf M. (rmagnus)


Lesenswert?

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.

von A. S. (Gast)


Lesenswert?

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.

von Stefan F. (Gast)


Lesenswert?

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.

von Sebastian (Gast)


Lesenswert?

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

von Dirk B. (dirkb2)


Lesenswert?

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.

von Schlaumaier (Gast)


Lesenswert?

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

von not true (Gast)


Lesenswert?

das funktioniert dann nicht mal mit den Libs-Funktionen
1
   #define TRUE 1
2
3
   char ch = 'a';
4
5
   if (isalpha (ch) == TRUE)
6
      puts ("Buchstabe");
7
   else
8
      puts ("Kein Buchstabe");

gibt "Kein Buchstabe" aus.

von not true (Gast)


Lesenswert?

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.

von Teo D. (teoderix)


Lesenswert?

Schlaumaier schrieb:
> Dumme Frage.
>
> Wieso definiert ihr ein Zustand den der Compiler eh als Festen Wert drin
> hat ?

Ist Evolutionär bedingt, bzw. ein Spätgeburt mit schiefer Hüfte.
Teo schrieb:
> C
> 
https://openbook.rheinwerk-verlag.de/c_von_a_bis_z/005_c_basisdatentypen_015.htm#mjea5fead98f181cf7573325643e428fa3
> C++
> http://userpage.fu-berlin.de/~ram/pub/pub_jf47ht81Ht/c++_wahrheitswert_literale


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

Nach dem Motto "Keine Arme, keine Kekse". :D

von Peter D. (peda)


Lesenswert?

P. S. schrieb:
> Schlicht und einfach:
> #include <stdbool.h>

Dann fehlt aber noch:
1
#define TRUE true
2
#define FALSE false

von Wolfgang (Gast)


Lesenswert?

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

von Einer K. (Gast)


Lesenswert?

Wolfgang schrieb:
> Da ist wieder der böse Vergleich mit TRUE.
1
#define FALSE 0
2
#define TRUE (!FALSE)
3
   char ch = 'a';
4
   if (!!isalpha (ch) == TRUE)
5
      puts ("Buchstabe");
6
   else
7
      puts ("Kein Buchstabe");
1
   char ch = 'a';
2
   if (isalpha (ch))
3
      puts ("Buchstabe");
4
   else
5
      puts ("Kein Buchstabe");

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
1
int irgendwas = 42;
2
_Bool testval = true;
3
4
if(testval == irgendwas) /?
5
if(testval == (_Bool)irgendwas) /!

von Sebastian (Gast)


Lesenswert?

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

von Schlaumaier (Gast)


Lesenswert?

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. ?!?! ;)

von Teo D. (teoderix)


Lesenswert?

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) /!

von Einer K. (Gast)


Lesenswert?

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.

von Christian H. (netzwanze) Benutzerseite


Lesenswert?

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.

von c-hater (Gast)


Lesenswert?

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

von Teo (Gast)


Lesenswert?

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

von Teo (Gast)


Lesenswert?

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.

von W.S. (Gast)


Lesenswert?

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.

von Stefan F. (Gast)


Lesenswert?

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.

von Rainer V. (a_zip)


Lesenswert?

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

von Wolfgang (Gast)


Lesenswert?

W.S. schrieb:
> 1 ist true

1 ist EIN Element der Menge der Werte, die true sind.

von Teo D. (teoderix)


Lesenswert?

Hmmm

bool x_bool;
int y_int;

x_bool = (y_int); OK
x_bool = y_int; -> Error?

?-/

von Sebastian (Gast)


Lesenswert?

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

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

Falk B. schrieb:
> Erstens braucht man bei einfachen Zahlen in einem #define KEINE Klammer,
> die braucht man nur bei Formeln.
1
#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.
1
#define TRUE !FALSE

Okay, ich folge mal Deinem Argument:
1
#include <stdio.h>
2
#define TRUE !FALSE
3
int main ()
4
{
5
    printf ("%d\n", TRUE);
6
    return 0;
7
}

Merkwürdigerweise gibt das Programm exakt "1" aus und nicht "jede Zahl 
ungleich Null".

Ich persönlich schreibe deshalb
1
#define TRUE 1
denn eine klare Tatsache umständlich zu verschleiern ist nicht 
zielführend.

: Bearbeitet durch Moderator
von Teo D. (teoderix)


Lesenswert?

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.

von Einer K. (Gast)


Lesenswert?

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

von Stefan F. (Gast)


Lesenswert?

Das ist doch ganz einfach:

- True hat den Wert 1, false hat den Wert 0
- Alle Werte ungleich 0 sind wahr

von Rainer V. (a_zip)


Lesenswert?

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

von Stefan F. (Gast)


Lesenswert?

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?
1
void zeigeWahrheit(uint8_t wert)
2
{
3
    if (wert==FALSE)
4
        puts("es ist falsch")
5
    else
6
        puts("es ist wahr");
7
}
8
9
zeigeWahrheit(FALSE);
10
zeigeWahrheit(!FALSE);

von Rainer V. (a_zip)


Lesenswert?

Stefan ⛄ F. schrieb:
> Meinst du das so?

...exakt so :-)
Gruß Rainer

von Einer K. (Gast)


Lesenswert?

Stefan ⛄ F. schrieb:
> if (wert==FALSE)

False ist hier unnötig.
 if (!wert)

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

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.

: Bearbeitet durch Moderator
von Falk B. (falk)


Lesenswert?

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!

von Wolfgang (Gast)


Lesenswert?

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.

von Rolf M. (rmagnus)


Lesenswert?

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.

von Falk B. (falk)


Lesenswert?

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

von Falk B. (falk)


Lesenswert?

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

von Wolfgang (Gast)


Lesenswert?

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:

von Wolfgang (Gast)


Lesenswert?

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 
;-)

von Teo D. (teoderix)


Lesenswert?

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

von A. S. (Gast)


Lesenswert?

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.

von Stefan F. (Gast)


Lesenswert?

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.

von BeBe (Gast)


Lesenswert?

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.

von Teo D. (teoderix)


Lesenswert?

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

von Rolf M. (rmagnus)


Lesenswert?

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.
5
>>> 3 == True
6
False
7
>>> 1 == True
8
True
9
>>>

von (prx) A. K. (prx)


Lesenswert?

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.

von Stefan F. (Gast)


Lesenswert?

Und Java lässt so einen Vergleich gar nicht zu.

von (prx) A. K. (prx)


Lesenswert?

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.

von Stefan F. (Gast)


Lesenswert?

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.

von BeBe (Gast)


Lesenswert?

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.

von Bauform B. (bauformb)


Lesenswert?

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.

von BeBe (Gast)


Lesenswert?

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

von Stefan F. (Gast)


Lesenswert?

>> heute scheißt man drauf, ob man ein Bit oder
>> ganze 64 bits für eine ja/nein Aussage belegt

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

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

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.

: Bearbeitet durch Moderator
von BeBe (Gast)


Lesenswert?

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

von (prx) A. K. (prx)


Lesenswert?

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.

von Wolfgang (Gast)


Lesenswert?

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
1
if (x)
denn sonst?

von (prx) A. K. (prx)


Lesenswert?

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.

?

von BeBe (Gast)


Lesenswert?

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.

von (prx) A. K. (prx)


Lesenswert?

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.

: Bearbeitet durch User
von Stefan F. (Gast)


Lesenswert?

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.

von BeBe (Gast)


Lesenswert?

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.

von BeBe (Gast)


Lesenswert?

Stefan ⛄ F. schrieb:
> Erwischt. Liegt wohl daran, dass das Buch wirklich sehr gut ist.

Ahhhhh, hoffentlich wirst Du jetzt nicht im Forum virtuell 
zerfleischt... :-)

von Stefan F. (Gast)


Lesenswert?

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.

von Wolfgang (Gast)


Lesenswert?

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

von (prx) A. K. (prx)


Lesenswert?

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.

: Bearbeitet durch User
von Stefan F. (Gast)


Lesenswert?

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.

von (prx) A. K. (prx)


Lesenswert?

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.

von (prx) A. K. (prx)


Lesenswert?

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.

: Bearbeitet durch User
von Schlaumaier (Gast)


Lesenswert?

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

von Wolfgang (Gast)


Lesenswert?

(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").

von Teo D. (teoderix)


Lesenswert?

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

von A. S. (Gast)


Lesenswert?

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.

von Rolf M. (rmagnus)


Lesenswert?

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
int a = 5;
2
int b = 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.

: Bearbeitet durch User
von Schlaumaier (Gast)


Lesenswert?

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.

von (prx) A. K. (prx)


Lesenswert?

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.

von A. S. (Gast)


Lesenswert?

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.

von Schlaumaier (Gast)


Lesenswert?

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

von (prx) A. K. (prx)


Lesenswert?

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.

: Bearbeitet durch User
von Rolf M. (rmagnus)


Lesenswert?

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.

: Bearbeitet durch User
von Schlaumaier (Gast)


Lesenswert?

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

von Stefan F. (Gast)


Lesenswert?

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.

von Stefan F. (Gast)


Lesenswert?

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.

von W.S. (Gast)


Lesenswert?

Wolfgang schrieb:
> 1 ist EIN Element der Menge der Werte, die true sind.

Sag ich doch!

W.S.

von Falk B. (falk)


Lesenswert?

OMG! 2 Mojito++, und der Rest ist trotzdem deutlich verschommener. 
Erklärung?

von Klaus W. (mfgkw)


Lesenswert?

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.

: Bearbeitet durch User
von c-hater (Gast)


Lesenswert?

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

von Klaus W. (mfgkw)


Lesenswert?

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.

von Yalu X. (yalu) (Moderator)


Lesenswert?

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.

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

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.

von Peter D. (peda)


Lesenswert?

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.

von Teo (Gast)


Lesenswert?

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.

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

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.

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


Lesenswert?

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.

von Egon D. (Gast)


Lesenswert?

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.

von (prx) A. K. (prx)


Lesenswert?

Dann nimmt halt die C-Shell statt Bourne. ;-)

von MaWin (Gast)


Lesenswert?

Wenn ich mir so triviale Dinge nicht merken könnte, würde ich mir Sorgen 
über meinen Gesundheitszustand machen.

von Egon D. (Gast)


Lesenswert?

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.

von Klaus W. (mfgkw)


Lesenswert?

Kommt vielleicht auf das Ziel an.

Wenn man das nicht verstanden hat, muss man halt was anderes machen.

von (prx) A. K. (prx)


Lesenswert?

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

von Egon D. (Gast)


Lesenswert?

(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?

von (prx) A. K. (prx)


Lesenswert?

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

von Peter D. (peda)


Lesenswert?

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

von (prx) A. K. (prx)


Lesenswert?

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.

: Bearbeitet durch User
von Teo (Gast)


Lesenswert?

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

von 🐧 DPA 🐧 (Gast)


Lesenswert?

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

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

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

: Bearbeitet durch Moderator
von Klaus W. (mfgkw)


Lesenswert?

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.

von Egon D. (Gast)


Lesenswert?

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

von Klaus W. (mfgkw)


Lesenswert?

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.

von A. S. (Gast)


Lesenswert?

Frank M. schrieb:
> Von daher hat das alles durchaus einen Sinn.

Ja. Ist ja auch ein sprachlicher Trugschluss, da es compare und nicht 
equal heisst.

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

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 ;-)

: Bearbeitet durch Moderator
von Roland F. (rhf)


Lesenswert?

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

von Egon D. (Gast)


Lesenswert?

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

von Klaus W. (mfgkw)


Lesenswert?

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.

von MaWin (Gast)


Lesenswert?

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.

von Klaus W. (mfgkw)


Lesenswert?

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.

von MaWin (Gast)


Lesenswert?

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.

von 🐧 DPA 🐧 (Gast)


Lesenswert?

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.

von (prx) A. K. (prx)


Lesenswert?

🐧 DPA 🐧 schrieb:
> 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.

"Rust Support In The Linux Kernel Undergoing Another Round Of 
Discussions"
https://www.phoronix.com/scan.php?page=news_item&px=Rust-For-Linux-April-2021-RFC

von MaWin (Gast)


Lesenswert?

🐧 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?

von 🐧 DPA 🐧 (Gast)


Lesenswert?

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.

von MaWin (Gast)


Lesenswert?

🐧 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?

von 🐧 DPA 🐧 (Gast)


Lesenswert?

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.

von MaWin (Gast)


Lesenswert?

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

von 🐧 DPA 🐧 (Gast)


Lesenswert?

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

von 🐧 DPA 🐧 (Gast)


Lesenswert?

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.

von MaWin (Gast)


Lesenswert?

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

von MaWin (Gast)


Lesenswert?

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

von 🐧 DPA 🐧 (Gast)


Lesenswert?

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.

von MaWin (Gast)


Lesenswert?

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

von MaWin (Gast)


Lesenswert?

🐧 DPA 🐧 schrieb:
> Bei Rust ist der Code sowohl das
> Interface, als auch die Implementation. Es gibt keine Trennung.

Das ist halt falsch.
Traits.

von Teo (Gast)


Lesenswert?

Falsch ist hier nur der Thread!
Husch husch, zurück... ;)
Beitrag "Re: Rust - ist das hier um zu bleiben?"

von 🐧 DPA 🐧 (Gast)


Lesenswert?

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

von MaWin (Gast)


Lesenswert?

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

von 🐧 DPA 🐧 (Gast)


Lesenswert?

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.

von Yalu X. (yalu) (Moderator)


Lesenswert?

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.

von Schlaumaier (Gast)


Lesenswert?

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.

von Klaus W. (mfgkw)


Lesenswert?

Schlaumaier schrieb:
> if X = true

das aber hoffentlich nicht in C :-)

von Rainer V. (a_zip)


Lesenswert?

🐧 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

von Stefan F. (Gast)


Lesenswert?

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.

von MaWin (Gast)


Lesenswert?

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.

von Stefan F. (Gast)


Lesenswert?

Selbst auf STM32 brauche ich ab und zu Assembler, nämlich für den NOP 
Befehl :-)

von (prx) A. K. (prx)


Lesenswert?

Rainer V. schrieb:
> Assembler, kennste einen, kennste alle...

Schon einmal einen NS SC/MP oder RCA 1802 programmiert?

von Sebastian W. (wangnick)


Lesenswert?

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

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


Lesenswert?

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

von Klaus W. (mfgkw)


Lesenswert?

| nur dann, wenn X ganz sicher ein bool ist...

Die Gefahr ist richtig.

Aber ich finde es lesbarer in der Art:
1
    int x = ....;
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).

: Bearbeitet durch User
von Rolf M. (rmagnus)


Lesenswert?

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.

von Michael F. (Firma: IAR Systems) (michael_iar)


Lesenswert?

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

von A. S. (Gast)


Lesenswert?

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.

von Egon D. (Gast)


Lesenswert?

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.

von (prx) A. K. (prx)


Lesenswert?

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.

von Michael F. (Firma: IAR Systems) (michael_iar)


Lesenswert?

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

von Klaus W. (mfgkw)


Lesenswert?

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

von Klaus W. (mfgkw)


Lesenswert?

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.

von Roland F. (rhf)


Lesenswert?

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.

von Schlaumaier (Gast)


Lesenswert?

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.

von W.S. (Gast)


Lesenswert?

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.

von Egon D. (Gast)


Lesenswert?

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?

von Rolf M. (rmagnus)


Lesenswert?

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.

von Egon D. (Gast)


Lesenswert?

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.

von Klaus W. (mfgkw)


Lesenswert?

ja, sorry - in C natürlich (bool)x statt bool(x).

von Yalu X. (yalu) (Moderator)


Lesenswert?

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)?

von Sebastian W. (wangnick)


Lesenswert?

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

von Egon D. (Gast)


Lesenswert?

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.

von Yalu X. (yalu) (Moderator)


Lesenswert?

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 :)

von 🐧 DPA 🐧 (Gast)


Lesenswert?

Egon D. schrieb:
> aus "Bundeskanzler" die Wurzel

Hab's mir eben ausgerechnet, das gibt: "3fxl31k.15g8"
1
> Math.sqrt(Number.parseInt("bundeskanzler", 36)).toString(36)
2
"3fxl31k.15g8"

von Egon D. (Gast)


Lesenswert?

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?

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