Forum: Compiler & IDEs Welchen Sinn hat der Datentyp "bool"?


von Dirk F. (dirkf)


Lesenswert?

Hallo,
verwende den freien Compiler XC32 von Microchip.
Habe jetzt festgestellt, das ein "bool"  die gleich Größe an Ram 
Speicher wie ein "char" verbraucht.
Warum sollten man dann überhaupt "bool" verwenden ?

Warum bekommt es ein moderner Compiler nicht hin, in ein Byte 8 bools zu 
packen ?????

: Bearbeitet durch User
von Oliver S. (oliverso)


Lesenswert?

Dirk F. schrieb:
> Warum bekommt es ein moderner Compiler nicht hin, in ein Byte 8 bools zu
> packen ?????

Warum sollte man das wollen? Den allermeisten sind die 8bits egal, die 
wollen Geschwindigkeit. Nur ein paar exotische Mikrocontroller-Nerds 
fahren auf solche Bitfrickeleien ab.

Oliver

von Andreas B. (abm)


Lesenswert?

Ineffizient. Ein Byte oder ein Wort lesen, dann die anderen Bits 
ausmaskieren kostet Zeit und Code. Beim Schreiben genauso. Ausnahme: Der 
Prozessor hat entsprechende Bit-Befehle, etwa MSC-51 oder bei ARM 
Bitbanding. Letzteres wird aber nur stiefmütterlich unterstützt und ist 
(deshalb?) bei neueren Typen gar nicht mehr vorhanden.

von Martin S. (sirnails)


Lesenswert?

Dirk F. schrieb:
> peicher wie ein "char" verbraucht.

Ja klar, was denn sonst? Speicherzellen sind numal mindestens 8 bit 
groß.

Dirk F. schrieb:
> Warum sollten man dann überhaupt "bool" verwenden ?

Warum sollte ich mich mit CHAR mit 255 Zuständen herumschlagen, wenn 
bool schon vom Compiler aus nur zwei Zustände kennt?

Dirk F. schrieb:
> Warum bekommt es ein moderner Compiler nicht hin, in ein Byte 8 bools zu
> packen ?????

Wieviel Speicher denkst Du denn, kostet es, sich zu merken, wo und an 
welcher Stelle der Bool ist?

von Michael B. (laberkopp)


Lesenswert?

Dirk F. schrieb:
> Warum sollten man dann überhaupt "bool" verwenden ?

Das dachten sich Kernigham&Ritchi auch.

> Warum bekommt es ein moderner Compiler nicht hin, in ein Byte 8 bools zu
> packen ????

Sie bekommen es hin, alles eine Frage wie gut der Compilerschreiberling 
war.

https://onlinedocs.microchip.com/oxy/GUID-BB433107-FD4E-4D28-BB58-9D4A58955B1A-en-US-5/GUID-1D1337FF-1B2E-4E4A-BDF3-31254932C478.html

Entscheidend ist, pointer auf Bits zu verbieten, damit
1
*register.bit3
kein Problem wird.

: Bearbeitet durch User
von Irgend W. (Firma: egal) (irgendwer)


Lesenswert?

Andreas B. schrieb:
> Ineffizient.

Jo! Einfach sich mal eine Makro bastel was sowas nachbildet und sich 
dann den Assembler output anschauen. Um 7-Bit Datenspeicher einzusparen, 
hat man dafür dann mehrere Byte an zusätzlichem Code bei jedem Zugriff 
darauf.

Im Prizip kann man sich sowas auch mit "bit field" nachbasteln, da 
erzeugt der Compiler dann den ganzen zusätzlichen Programmcode im 
Hintergrund:
- https://en.cppreference.com/w/c/language/bit_field

von Dirk F. (dirkf)


Lesenswert?

OK, Danke. Verstanden.

von Michael B. (laberkopp)


Lesenswert?

Irgend W. schrieb:
> Um 7-Bit Datenspeicher einzusparen, hat man dafür dann mehrere Byte an
> zusätzlichem Code bei jedem Zugriff darauf.

Nicht unbedingt, wie uC haben Bitadressierungszugriffsarten, da ist das 
1 Befehl.

Ob der Compiler sie effizient nutzt, wie ein Assemblerprogrammierer, sei 
dahingestellt, viele Compiler sind strohfoof.

von Teo D. (teoderix)


Lesenswert?

Dirk F. schrieb:
> Warum bekommt es ein moderner Compiler nicht hin, in ein Byte 8 bools zu
> packen ?????

Tut er doch! ... Wenn möglich und GEWÜNSCHT.
Also auf die Optimierungsstufe achten! (Standard für lau tut/tat!)
(Zuletzt mit V5.x verwendet und geprüft. Nich weils nötig war, nur haben 
wollen, mus so sein etc. :)

von Dirk F. (dirkf)


Lesenswert?

Teo D. schrieb:
> Zuletzt mit V5.x verwendet

Von welchem Compiler redest Du ?

Ich:   XC32 Version 4.35

von Teo D. (teoderix)


Lesenswert?

Dirk F. schrieb:
> Von welchem Compiler redest Du ?
>
> Ich:   XC32 Version 4.35

Ubs, völlig verplant... Das war die IDE Version. :}
XC8 2,36 Ja, andere Baustelle aber ich könnt mein linken Schuh drauf 
verwetten...
Wenn ich mich recht erinnere, hab ich die alle als Global anlegen 
müssen(?)  und das Progrämmchen war wirklich mehr überschaubar.

von Joe (Gast)


Lesenswert?

Teo D. schrieb:
> Dirk F. schrieb:
>> Warum bekommt es ein moderner Compiler nicht hin, in ein Byte 8 bools zu
>> packen ?????
>
> Tut er doch! ... Wenn möglich und GEWÜNSCHT.
> Also auf die Optimierungsstufe achten! (Standard für lau tut/tat!)
> (Zuletzt mit V5.x verwendet und geprüft. Nich weils nötig war, nur haben
> wollen, mus so sein etc. :)

Ist das Chinesisch? Lau tut tat? Bitte uebersetze doch Mal.

von Harald K. (kirnbichler)


Lesenswert?

Joe schrieb:
> Lau tut tat?

"für lau" == umsonst (aber nicht vergebens), "für umme", kostenfrei, 
gratis

tut = macht etwas jetzt, Gegenwart
tat = machte etwass früher mal, Vergangenheit

von Teo D. (teoderix)


Lesenswert?

Harald K. schrieb:
> tat = machte etwass früher mal, Vergangenheit

Tat = Schreibfehler -> Dat = Das/Dieses :DDD

von Harald K. (kirnbichler)


Lesenswert?

Teo D. schrieb:
> Tat = Schreibfehler

Klingt in diesem Kontext dann aber komplett bizarr:

> Also auf die Optimierungsstufe achten! (Standard für lau tut/tat!)
> (Zuletzt mit V5.x verwendet und geprüft.

Ich hatte mir das so ins Hochdeutsche übersetzt:

Also auf die Optimierungsstufe achten, die [im XC8] kostenlose 
Standardoptimierung genügt bzw. genügte früher, als ich [Teo] das mit 
V5.x [des XC8] nutzte.

---

Oh, meine Fehlschreibung "etwass" ist peinlich, da muss die Tastatur 
geprelllllllllt und ich Blindfisch das nicht gesehen haben.

von Bruno V. (bruno_v)


Lesenswert?

Also:

 * Pointer
 * Maskierung
 * Race Conditions
 * Shift-Aufwand (Zuweisung)

Wobei der fehlende Ptr viele weitere Dinge impliziert, z.b. Ansicht im 
Debugger, Arraxs, memcpy, sizeof...

von Klaus K. (Gast)


Lesenswert?

> Warum sollten man dann überhaupt "bool" verwenden ?

Damit man quasi "natursprachlichen" Code niederschreiben kann.

OK, für einen englisch-sprecher ist der Verständnisvorteil 
offensichtlicher:
1
if (motorenabled)  led_red = 0xFF;  //statt 
2
3
4
if (motorenabled != 0)  led_red = 0xFF;  // oder
5
6
7
if (motorenabled == 0xFF)  led_red = 0xFF;

mit dem Schlüsselwort "then" wäre es noch "natürlicher"

Auf deutsch und auf  "magic numbers" verzichtet:
1
 falls motorangeschaltet dann Rotlicht = VOLL;

aber wer  lässt sich schon c-code "vorlesen" oder legt Wert darauf, das 
auch C-Unkundige verstehen könnten was das Programmieräffchen da 
zusammengekritzelt hat hat...

von Hmmm (hmmm)


Lesenswert?

Klaus K. schrieb:
> if (motorenabled)  led_red = 0xFF;  //statt
>
> if (motorenabled != 0)  led_red = 0xFF;

Dafür braucht man keine Bools, if(motorenabled) würde auch mit einem int 
o.dgl. funktionieren.

Klaus K. schrieb:
> Programmieräffchen

Der obige Griff ins Klo macht diese Äusserung noch peinlicher.

von Percy N. (vox_bovi)


Lesenswert?

Hmmm schrieb:
> Dafür braucht man keine Bools, if(motorenabled) würde auch mit einem int
> o.dgl. funktionieren.

Klar, damit geht dann auch

motorenabled ++

Wer weiß, vielleicht möchte man ja mal mitteilen, der Motor sei "doppelt 
plus an". Schönen Gruß an Herrn Blair!

von Klaus W. (mfgkw)


Lesenswert?

Hmmm schrieb:
> Dafür braucht man keine Bools, if(motorenabled) würde auch mit einem int
> o.dgl. funktionieren.
> ...

Es geht natürlich beides.
Mit bool kann man in C nicht mehr machen als auch mit int oder char 
möglich ist.

Aber mit bool drückt man klar aus, daß man nicht mit einer von vielen 
möglichen Zahlen hantieren will, sondern mit "ja" oder "nein".

(Es soll Leute geben, die lesbare Programme bevorzugen.)


In C++ wird es dann interessanter, weil da mehr auf Typen geachtet wird. 
Bspw. beim Überladen von Funktionen kann ein Aufruf mit einer bool etwas 
anderes sein als ein Aufruf mit einer Zahl.

Man könnte eine Funktion, die Werte ausgibt, z.B. für bool anders 
überladen als für char oder int:
1
    bool b = false;
2
    char c = 'A';
3
    int  i = 42;
4
    ...
5
    print( b ); // könnte "false" ausgeben oder "no" statt 0
6
    print( c ); // könnte A ausgeben statt 65
7
    print( i ); // könnte 42 ausgeben

Oder streams (vulgo files, wie std::cout als Standardausgabe, oder eine 
echte Datei):
Wenn man so einen stream an etwas übergibt, was einen stream erwartet, 
wird er halt als stream behandelt. f.write(...) würde also etwas in die 
Datei f schreiben, und wieder f zurückliefern.
Benutzt man einen stream aber in einem logischen Ausdruck, wird er in 
bool konvertiert. Diese Konvertierung ist für streams aber so überladen, 
daß sie true ergibt, wenn der stream noch funktioniert, oder false, wenn 
nicht (z.B. Fehler aufgetreten).
Das ermöglicht eine Konstruktion wie:
1
    while( f.read(...) ) tuwas...
, weil while einen logischen Ausdruck braucht und die Konvertierung von 
f nach bool den Status des streams liefert.

Wer also meint, bool ist überflüssig, der hat eigentlich recht und darf 
gerne ohne bool weiter herumstümpern :-)

von Wladimir (vril_2023)


Lesenswert?

Ich denke, dass bool beim C99 Standard extra für die Pascal und Basic - 
Koryphäen eingeführt wurde, weil die damals auch mal C probieren 
wollten!

von Teo D. (teoderix)


Lesenswert?

Auch Nichtkoryphäen, haben da gerne mit Defines, ihre Programme 
aufgehübscht.

Wurde grad von XC8 (2.36) enttäuscht.
Hab mal auf die schnelle, einer Funktion mit Booleschen Rückgabewert, ne 
Zahl >1 zugewiesen. Nich mal ne Warnung (-9) gibts. :´(

von Dirk F. (dirkf)


Lesenswert?

Teo D. schrieb:
> Wurde grad von XC8 (2.36) enttäuscht.

Ich meine beim XC8 Compiler gibt es doch den Datentyp "bit"
Den vermisse ich beim XC32.....

von Joe (Gast)


Lesenswert?

Harald K. schrieb:
> Oh, meine Fehlschreibung "etwass" ist peinlich, da muss die Tastatur
> geprelllllllllt und ich Blindfisch das nicht gesehen haben.


Maddonix iddonetlimm!

(Macht fast gar nichts, ist wirklich nicht so schlimm)

von Bruno V. (bruno_v)


Lesenswert?

Teo D. schrieb:
> ne Zahl >1 zugewiesen. Nich mal ne Warnung (-9) gibts

Ist ja eigentlich auch nicht schlimm:

 * Mit 1/true/!0/!false vergleicht man eh nicht
 * Warnungen macht Lint oder Co

Auf die Schnauze fällt man dann, wenn man es einem bitfeld-bool zuweist.


(Seit einiger Zeit nutze ich 0/1 statt false/true. Keine Ahnung, warum 
ich das geringfügig besser lesbar finde, trotz verwechselungsgefahr mit 
integerwert)

von Teo D. (teoderix)


Lesenswert?

Bruno V. schrieb:
> Teo D. schrieb:
>> ne Zahl >1 zugewiesen. Nich mal ne Warnung (-9) gibts
>
> Ist ja eigentlich auch nicht schlimm:

Aber ne Warnung wärs wert, denke ich.

Ich glaub, ein paar Synapsen tuns grad wieder...
Wenn ich mich recht erinnere, ist beim XC8 bool, auch nur ein Makro mit 
_bit. Das in ein Byte stopfen, geht denke ich, da auch nur mit 
statischen.

von Klaus K. (Gast)


Lesenswert?

Wladimir schrieb:
> Ich denke, dass bool beim C99 Standard extra für die Pascal und Basic -
> Koryphäen eingeführt wurde, weil die damals auch mal C probieren
> wollten!

bool in Basic ?  Hatte der 9kbyte grosse Interpreter des C64 überhaupt 
Platz für solchen Zuckerguß?

https://www.c64-wiki.de/wiki/C64-Befehle

Und klar, das "boolean" als Hochsprachenkonstrukt von Embedded Hackern 
die C eher als eine Art "Assembler für Warmduscher" verwenden, 
weitgehend ignoriert wird.

Dabei kann man mit passender Typisierung viele Fehler vermeiden bzw. 
schon im Compiler abfangen. Es sind schon Raketen abgestürzt wegen dem 
falschen typ.

von Rolf M. (rmagnus)


Lesenswert?

Klaus K. schrieb:
> Wladimir schrieb:
>> Ich denke, dass bool beim C99 Standard extra für die Pascal und Basic -
>> Koryphäen eingeführt wurde, weil die damals auch mal C probieren
>> wollten!
>
> bool in Basic ?  Hatte der 9kbyte grosse Interpreter des C64 überhaupt
> Platz für solchen Zuckerguß?

1999 ist für den C64 etwas spät. Das war 5 Jahre nach EOL. Es war eher 
so die Zeit, als sie alle mit Visual Basic hantiert haben, das es da 
schon seit 8 Jahren gab.

: Bearbeitet durch User
von Klaus K. (Gast)


Lesenswert?

> 1999 ist für den C64 etwas spät. Das war 5 Jahre nach EOL. Es war eher
> so die Zeit, als sie alle mit Visual Basic hantiert haben, das es da
> schon seit 8 Jahren gab.

Naja, wenn man "Visual Basic" meint sollte man auch "visual Basic" 
schreiben und nicht "BASIC". Und bei den amüsanten Vergleich zwischen 
C99 und "dem Rest der welt" geht es wohl eher um die Unterscheidung in 
"stark" und "Schwach" typisierte Sprachen.
https://de.wikipedia.org/wiki/Typisierung_(Informatik)#Beispiele

Und das alle mit Visual Basic hantiert hätten ... IMHO gab es da mehr 
als das sprichwörtliche Gallische Dorf die ihren eigenen Zaubertrabk 
köchelten und damit in die Schlacht zogen: (Borland-) Pascal, ADA, 
Modula-2, Lisp, Forth, Erlang, ....

Wobei ohne Betrachtung des Anwendungsgebietes ist diese Einteilung IMHO 
allein zweckfrei. Esy geht halt darum, ob man in konkreten Anwendung 
Vorteile durch die Verwendung von "passenden Typen" hat. Der Prozessor 
selbt hat hat nur die Typen Datenbusbreite (char, int) und pointer auf 
Speicherzelle an Datenbus. Damit kommt dann auch der Embedded Coder 
besten aus.

Und dann gibt es Applikationen, die abstrakt weit weg vom Prozessor 
sind, beispielsweise GUI oder natursprachlich formulierte 
Ablaufsteuerungen, Datenbanken, ...  die sind dann eher für 
"Hochsprachen und ihre Concepte" geeignet, da möchte man nicht die 
Programmlogik durch Maschinendetails "verbogen" sehen.

von Rolf M. (rmagnus)


Lesenswert?

Klaus K. schrieb:
> Naja, wenn man "Visual Basic" meint sollte man auch "visual Basic"
> schreiben und nicht "BASIC".

Da stand "Basic", nicht "BASIC", und da das BASIC vom C64 zu der Zeit 
keine Rolle mehr gespielt hat und wie du richtig angemerkt hast, auch 
keinen bool-Typ hat, war das offensichtlich nicht gemeint.

> Und bei den amüsanten Vergleich zwischen C99 und "dem Rest der welt" geht
> es wohl eher um die Unterscheidung in "stark" und "Schwach" typisierte
> Sprachen.
> https://de.wikipedia.org/wiki/Typisierung_(Informatik)#Beispiele

Es ging um die Frage, warum C99 einen Typ bool eingeführt hat. Das hat 
erst mal nicht soviel damit zu tun, dass C schwach typisiert ist. Es ist 
eher so, dass es deswegen nicht zwingend ein bool gebraucht hat und 
daher anfangs keins hatte. Schließlich funktioniert ja z.B. in einem if 
auch ein beliebiger numerischer oder Zeiger-Typ als Bedingung.

> Und das alle mit Visual Basic hantiert hätten ... IMHO gab es da mehr
> als das sprichwörtliche Gallische Dorf die ihren eigenen Zaubertrabk
> köchelten und damit in die Schlacht zogen: (Borland-) Pascal, ADA,
> Modula-2, Lisp, Forth, Erlang, ....

Mit "alle" meinte ich alle, die irgendwas mit Basic am Hut haben, nicht 
alle Programmierer weltweit. C64-BASIC war 1999 nicht mehr so gefragt.

> Wobei ohne Betrachtung des Anwendungsgebietes ist diese Einteilung IMHO
> allein zweckfrei. Esy geht halt darum, ob man in konkreten Anwendung
> Vorteile durch die Verwendung von "passenden Typen" hat.

Ja, deshalb hat man ja Hochsprachen.

> Und dann gibt es Applikationen, die abstrakt weit weg vom Prozessor
> sind, beispielsweise GUI oder natursprachlich formulierte
> Ablaufsteuerungen, Datenbanken, ...  die sind dann eher für
> "Hochsprachen und ihre Concepte" geeignet, da möchte man nicht die
> Programmlogik durch Maschinendetails "verbogen" sehen.

Wobei es natürlich trotzdem meist gewisse Randbedingungen gibt.

von Rbx (rcx)


Lesenswert?

Dirk F. schrieb:
> Warum sollten man dann überhaupt "bool" verwenden ?

Damit man Hochsprachencode mit "true" und "false". schreiben kann. Mir 
fällt es aber trotzdem leichter, logische Operationen z.B. in Bitfeldern 
zu verarbeiten.

Von Flags, logischen Operationen mit Registern, um diese zu setzen, und 
lustigem Hin- und Herspringen willst du lieber nichts wissen.. ;)
Abfragen wie or ax,ax gleich an den Anfang einer (bestimmten) Schleife 
zu setzen, hatte mir mal ein professioneller Programmierer beigebracht.
Der Code von dem sah im Debugger auch super aus. Aber der konnte auch 
gut coden.

Von der Performance her sind auch Algorithmen sehr beliebt, wie auch 
effektiv.

: Bearbeitet durch User
Beitrag #7555481 wurde vom Autor gelöscht.
von Daniel G. (denial)


Lesenswert?

Irgendwie übersehen hier alle, dass ein C99 bool die tolle Eigenschaft 
hat, dass er immer 0 oder 1 ist. Man braucht auch beim Casten von 
größeren Datentypen keine Angst zu haben, dass nur die unteren Bits 
beachtet werden. 0x40000 in einen bool mit sizeof(bool) == 1 zu casten, 
liefert 1. Das gleiche in einen uint8_t zu casten, liefert 0.

von Tim T. (tim_taylor) Benutzerseite


Lesenswert?

Daniel G. schrieb:
> Irgendwie übersehen hier alle, dass ein C99 bool die tolle Eigenschaft
> hat, dass er immer 0 oder 1 ist. Man braucht auch beim Casten von
> größeren Datentypen keine Angst zu haben, dass nur die unteren Bits
> beachtet werden. 0x40000 in einen bool mit sizeof(bool) == 1 zu casten,
> liefert 1. Das gleiche in einen uint8_t zu casten, liefert 0.

Tja, wer zu doof zum casten ist, sollte es lassen.
1
uint8_t KleinerDatentyp = GrosserDatentyp ? 1 : 0;

: Bearbeitet durch User
von Bruno V. (bruno_v)


Lesenswert?

Tim T. schrieb:
> Tja, wer zu doof zum casten ist, sollte es lassen.

Der übliche kurze Hack ist !! (Bei einem Argument, sonst && oder ||)

Es ist aber super, wenn man gar keinen Hack braucht.

von Bruno V. (bruno_v)


Lesenswert?

Rbx schrieb:
> Abfragen wie or ax,ax gleich an den Anfang einer (bestimmten) Schleife

Hast Du mal ein Beispiel? Oder geht es nur um Assembler-Hacks

von Klaus K. (Gast)


Lesenswert?

Daniel G. schrieb:
> Irgendwie übersehen hier alle, dass ein C99 bool die tolle Eigenschaft
> hat, dass er immer 0 oder 1 ist. Man braucht auch beim Casten von
> größeren Datentypen keine Angst zu haben, dass nur die unteren Bits
> beachtet werden.

Ein boolean wird nie gecastet, ein boolean wird nur in 
Bedingungsoperatoren wie if () etc verarbeitet.
Siehe auch Beitrag "Re: Welchen Sinn hat der Datentyp "bool"?" und 
Matthäus 5,37 .

von Rolf M. (rmagnus)


Lesenswert?

Klaus W. schrieb:
> Benutzt man einen stream aber in einem logischen Ausdruck, wird er in
> bool konvertiert.

Wobei es in C++98 ulkigerweise noch void* statt bool war. Und dieser war 
dann je nach Stream-Status ein Nullpointer oder nicht.

Beitrag #7556325 wurde vom Autor gelöscht.
von Rbx (rcx)


Lesenswert?

Bruno V. schrieb:
> Hast Du mal ein Beispiel? Oder geht es nur um Assembler-Hacks

Es geht nur um eine Bedingungsprüfung.
Du könntest auch IF(ax) schreiben.

In Asm geht aber die Schleifenkonstruktion etwas anders als in C, und 
Asm-Schleifen sind auch nicht so stark standardisiert.
Beim Intel gibt es aber Befehlserleichterungen wie loop oder repz und 
auch die Register wie SI und DI z.B. für Richtungsabarbeitungen.
Mit "Hacks" hat das nichts zu tun.
Mit in logischen Operationen gut sein, aber schon.

von Bruno V. (bruno_v)


Lesenswert?

Rbx schrieb:
> In Asm geht aber die Schleifenkonstruktion etwas anders als in C

M.E. doch Assembler-Hacks. Z.B. XOR zum löschen eines Registers oder 
swap Zweier.

Also was als Pattern für seinen Assembler lernt und der C-Compiler auch 
kennt.

von Falk S. (falk_s831)


Lesenswert?

>> Warum sollten man dann überhaupt "bool" verwenden ?
>
> Warum sollte ich mich mit CHAR mit 255 Zuständen herumschlagen, wenn
> bool schon vom Compiler aus nur zwei Zustände kennt?

Jo, genau - hilft zur Vermeidung von Seiteneffekten bei z.B. 
Rückgabewerten.

Angenommen musst nen Test schreiben, und musst potentiell alle 
Restklassen eines chars durchklappern, weil jemand auf Platz optimiert 
hat. Kann zwar auch sinnvoll sein, kommt aber drauf an. Pauschal da nur 
2 Zustände brauchen zu müssen, könnte man halt irgendwie dezent als 
etwas sauberer erachten.

von Markus F. (mfro)


Lesenswert?

ich hätte ja nichts dagegen, wenn ein bool auch tatsächlich ein bool 
wäre.

Ich habe aber noch keinen (C-) Compiler gesehen, der bei
1
static bool b = 12;
einen Fehler oder auch nur eine Warnung ausgespuckt hätte. So ist das 
keine Spur besser als
1
#define bool int

von Oliver S. (oliverso)


Lesenswert?

Markus F. schrieb:
> Ich habe aber noch keinen (C-) Compiler gesehen, der bei
> static bool b = 12;
> einen Fehler oder auch nur eine Warnung ausgespuckt hätte.

Selbst bei den C++ Compilern warnt nur MSVC, die anderen nur bei
1
static bool b {12};

Oliver

: Bearbeitet durch User
von Rolf M. (rmagnus)


Lesenswert?

Markus F. schrieb:
> ich hätte ja nichts dagegen, wenn ein bool auch tatsächlich ein bool
> wäre.

Ein bool ist ein bool ist ein bool.

> Ich habe aber noch keinen (C-) Compiler gesehen, der bei
> static bool b = 12;
> einen Fehler oder auch nur eine Warnung ausgespuckt hätte.

Das liegt aber nicht daran, dass es kein bool wäre, sondern daran, dass 
ein int implizit nach bool konvertiert werden kann. In b steht nachher 
nämlich trotzdem keine 12 drin.

> So ist das keine Spur besser als
> #define bool int

Doch, denn da stünde nachher 12 drin.

von Armin K. (-donald-) Benutzerseite


Lesenswert?

Codevision AVR kann mit bool umgehen und macht die auch wirklich nur ein 
bit breit in einem Register.

von Peter D. (peda)


Lesenswert?

Markus F. schrieb:
> Ich habe aber noch keinen (C-) Compiler gesehen, der bei static bool b =
> 12;
> einen Fehler oder auch nur eine Warnung ausgespuckt hätte. So ist das
> keine Spur besser als #define bool int

Nö, da ist ein großer Unterschied.
C macht eine automatische Konvertierung auf den Zieltyp ohne Warnung.
Aus 12 wird also b = true d.h. b = 1.

: Bearbeitet durch User
von Rainer W. (rawi)


Lesenswert?

Peter D. schrieb:
> Aus 12 wird also b = true d.h. b = 1.

b=12 ist auch true

von Bruno V. (bruno_v)


Lesenswert?

Rainer W. schrieb:
> b=12 ist auch true

Das ist missverständlich: Alles != 0 (also auch 12) wird zu true 
gewandelt, wenn eine boolsche Entscheidung gebraucht wird (z.B. bei if, 
while, ...).

if(b==true) ist hingegen nur erfüllt, wenn b ein bool ist, nicht wenn es 
ein int ist.

Bei if & Co behilft man sich, indem man niemals auf true vergleicht 
(was den code oft besser macht). Bei Zuweisungen erfordert es jedoch 
Klimmzüge:
1
int     myBool_b = 256;
2
uint8_t myBool_c = b;   /* geht schief */
3
uint8_t myBool_d = !!b; /* Klimmzug */

von Rolf M. (rmagnus)


Lesenswert?

Rainer W. schrieb:
> Peter D. schrieb:
>> Aus 12 wird also b = true d.h. b = 1.
>
> b=12 ist auch true

b=12 geht aber eben nicht, weil b ein bool ist, der den Wert 12 nicht 
annehmen kann.

von Wf88 (wf88)


Lesenswert?

Rolf M. schrieb:
> b=12 geht aber eben nicht, weil b ein bool ist, der den Wert 12 nicht
> annehmen kann.

Wie ist das vorgegeben? Meckert der compiler dann, oder macht er einfach 
still ein TRUE (1) aus der 12?

von Daniel A. (daniel-a)


Lesenswert?

Der eigentliche Grund für die Bools ist, dass man einen richtigen, 
boolschen statt binären, postfix toggle Operator haben wollte:

https://godbolt.org/z/GGrsrEoYP
1
#include <stdio.h>
2
#include <stdbool.h>
3
4
int main(int argc, char** argv){
5
    bool b = true;
6
    for(int i=0; i<10; i++)
7
        puts(b-- ? "On" : "Off");
8
}

von Udo K. (udok)


Lesenswert?

Wf88 schrieb:
> Wie ist das vorgegeben? Meckert der compiler dann, oder macht er einfach
> still ein TRUE (1) aus der 12?

Er macht ein TRUE (1) aus der 12.

Der Vorteil von bool (oder BOOL) ist, dass die Absicht des 
Programmierers klar ist, unabhängig ob der darunterliegende Datentyp ein 
INT oder ein BYTE ist.

// Hier weiss ich dass die Funktion TRUE liefert, wenn alles passt.
// Im Fehlerfall wird FALSE zurückgeliefert.
BOOL doSomething()

// Hier liefert die Funktion üblicherweise 0, wenn alles passt.
// Im Fehlerfall wird ein Fehlercode zurückgeliefert.
INT doSomething()

von Rolf M. (rmagnus)


Lesenswert?

Wf88 schrieb:
> Rolf M. schrieb:
>> b=12 geht aber eben nicht, weil b ein bool ist, der den Wert 12 nicht
>> annehmen kann.
>
> Wie ist das vorgegeben? Meckert der compiler dann, oder macht er einfach
> still ein TRUE (1) aus der 12?

Eine Konvertierung von int nach bool macht wie oben angegeben aus 0 ein 
false, aus allem anderen ein true. Umgekehrt macht eine Konvertierung 
von bool nach int aus false eine 0 und aus true eine 1. Dabei können 
solche Konvertierungen implizit durchgeführt werden, also "still". 
Folgendes C-Programm gibt daher 1 aus:
1
#include <stdio.h>
2
#include <stdbool.h>
3
int main()
4
{
5
    int i = 12;
6
    bool b = i;
7
    int j = b;
8
    printf("%d\n", j);
9
}

: Bearbeitet durch User
von Peter D. (peda)


Lesenswert?

Udo K. schrieb:
> // Hier liefert die Funktion üblicherweise 0, wenn alles passt.
> // Im Fehlerfall wird ein Fehlercode zurückgeliefert.
> INT doSomething()

Oder bei getchar():
0 .. 0xFF = gültiges Datenbyte
EOF (-1) = end of file

von Oliver S. (oliverso)


Lesenswert?

Rolf M. schrieb:
> Dabei können
> solche Konvertierungen implizit durchgeführt werden, also "still".
> Folgendes C-Programm gibt daher 1 aus:

Die Konvertierungen können nicht nur implizit, also "still" durchgeführt 
werden, die werden grundsätzlich implizit, also "still" durchgeführt. 
Was dann zu der oben angemoserten Eigenschaft führt, das der Compiler 
nicht warnt.

Oliver

von Wf88 (wf88)


Lesenswert?

Danke für die geduldigen Erläuterungen, auch wenn ich das aus den voran 
gegangenen Posts hätte heraus lesen können.

von Rolf M. (rmagnus)


Lesenswert?

Oliver S. schrieb:
> Rolf M. schrieb:
>> Dabei können
>> solche Konvertierungen implizit durchgeführt werden, also "still".
>> Folgendes C-Programm gibt daher 1 aus:
>
> Die Konvertierungen können nicht nur implizit, also "still" durchgeführt
> werden, die werden grundsätzlich implizit, also "still" durchgeführt.

Man kann sie per Cast durchaus auch explizit machen, wenn man das will:
1
   bool b = (bool)i;
Aber es ist in dem Fall nicht nötig, weil die implizite Konvertierung 
genauso geht.

Peter D. schrieb:
> Oder bei getchar():
> 0 .. 0xFF = gültiges Datenbyte
> EOF (-1) = end of file

Was überaus ungeschickt gemacht ist, denn char kann auch signed sein, 
also einen Wertebereich von -0x80 bis 0x7F haben.

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

Rolf M. schrieb:
> Was überaus ungeschickt gemacht ist, denn char kann auch signed sein,
> also einen Wertebereich von -0x80 bis 0x7F haben.

Der Return-Wert von getchar() ist int. Schon der erste Kernighan-Ritchie 
benutzte
1
  int c = getchar();
Ein char ist hier überhaupt nicht im Spiel.

Das K&R-Kopierprogramm
1
int main ()
2
{
3
    int c;
4
5
    while ((c = getchar()) != EOF)
6
    {
7
        putchar (c)
8
    }
9
    return 0;
10
}
funktioniert auch anstandslos auf Systemen, wo char signed sein kann. 
Die Verwendung von char in der Zuweisung wäre aber hier ein Fehler - 
nämlich des Programmierers, nicht der Bibliotheksfunktion.

: Bearbeitet durch Moderator
von Udo K. (udok)


Lesenswert?

Was aber nicht funktioniert:
1
int c = getchar();
2
3
if (c == -1)
4
{
5
    Error()
6
}
7
else if (c == 'ä')
8
{
9
    NeverCalled()
10
}
11
else if (c == 'a')
12
{
13
    Ok()
14
}

: Bearbeitet durch User
von Wf88 (wf88)


Lesenswert?

Udo K. schrieb:
> 'ä'

Weil für ein 'ä' brauchst du anderes Charset als das default.

von Daniel A. (daniel-a)


Lesenswert?

Doch, das mit dem Wertebereich von Char ist tatsächlich ein Problem, 
egal, ob ich die jetzt in ein int oder ein char packe. Ich konvertiere 
die dann immer erstmal nach unsigned char, bevor ich die weiter 
auswerte. Mir ist es schon passiert, dass ich ein Case in einem Switch 
hatte, und dann war das Zeichen negativ!

Der Wert von EOF ist aber auch Implementationsspezifisch, der wird fast 
überall auf was ausserhalb vom char Bereich gesetzt, egal ob char nun in 
der Implementation signed oder unsigned ist. Der Wert von EOF ist also 
in der Regel kein Problem.

Blöd ist nur, wenn man im selben Switch EOF und 0x80 prüfen will. Dann 
kann man nicht einfach nach "unsigned char" casten. Ok, '\x80' müsste 
dann eigentlich gehen. Aber so einen Fehler muss man erst mal finden!

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

Udo K. schrieb:
> else if (c == 'ä')

Bei ISO8859 funktioniert das durchaus. c hat dann nämlich einen 
positiven Wert, nämlich 0xE4 - auch wenn auf dem System char signed 
wäre. Beachte, dass Du "int c" geschrieben hast, nicht "char c".

getchar() liefert folgenden Wertebereich:

0 bis 255, -1 bei EOF - auch auf Systemen, wo char signed ist.

Ich wiederhole: bei getchar() ist überhaupt kein char im Spiel!

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

Daniel A. schrieb:
> Mir ist es schon passiert, dass ich ein Case in einem
> Switch hatte, und dann war das Zeichen negativ!

Natürlich kann das passieren, wenn Du char als Type verwendest. Das hat 
aber nichts mit getchar() zu tun.

Ich antwortete auf folgenden Satz:

Rolf M. schrieb:
> Was überaus ungeschickt gemacht ist, denn char kann auch signed sein,
> also einen Wertebereich von -0x80 bis 0x7F haben.

Dieser bezog sich auf getchar(). Und darauf habe ich geantwortet. Dass 
Du jetzt darauf ansprichst, weil Du mal den Fehler gemacht hast, einen 
signed char buffer zu verwenden, hat mit getchar() überhaupt nichts zu 
tun.

Wenn Du Zeichen speichern(!) willst, dann natürlich unsigned char:
1
int main ()
2
{
3
    unsigned char buffer[20];    // Hier unsigned char verwenden!
4
    int           c;             // hier int verwenden!
5
    int           i = 0;
6
7
    while ((c = getchar ()) != EOF)
8
    {
9
        buffer[i++] = c;
10
        if (i == 20 - 1)
11
        {
12
            exit(1);  // zu lang
13
        }
14
    }
15
    buffer[i] = '\0';
16
    printf ("Die ersten 20 Zeichen: %s\n", buffer);
17
}

Aber zum Auswerten des Rückgabewertes von getchar() brauchst Du 
weiterhin ein int!

: Bearbeitet durch Moderator
von Daniel A. (daniel-a)


Lesenswert?

Ich hab gerade nochmal nachgesehen, was der Standard sagt. Die Zeichen 
die getchar zurückgibt sind tatsächlich als ob sie vorher nach unsigned 
char konvertiert wurden.
Und EOF muss negativ sein, aber es muss nicht zwingend -1 sein.

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

Daniel A. schrieb:
> Ich hab gerade nochmal nachgesehen, was der Standard sagt. Die Zeichen
> die getchar zurückgibt sind tatsächlich als ob sie vorher nach unsigned
> char konvertiert wurden.
> Und EOF muss negativ sein, aber es muss nicht zwingend -1 sein.

Eben. Wenn Du eine int-Variable nimmst, um den Rückgabewert von 
getchar() zu testen, bist Du immer im grünen Bereich. Von daher ist 
gar nichts "ungeschicktes" an der Funktion getchar(). Diese hat 1970 
schon anstandslos mit Binärdateien funktioniert und funktioniert auch 
heute noch mit 8-Bit-Zeichensätzen wie ISO8859 oder UTF-8.

von Daniel A. (daniel-a)


Lesenswert?

Was mir aber gerade aufgefallen ist, bei Zeichenkonstanten ist das nicht 
festgelegt, ob wohl die auch vom typ int sind. Hier ein Beispiel, wo es 
negativ raus kommt: https://godbolt.org/z/z8xG7G4Wv

Vermutlich ist es das, was ich in der Regel verwechsle. Da nimmt man 
extra '' für Zeichen im Switch, und dann sind die negativ!

von Daniel A. (daniel-a)


Lesenswert?

Frank M. schrieb:
> Daniel A. schrieb:
>> Mir ist es schon passiert, dass ich ein Case in einem
>> Switch hatte, und dann war das Zeichen negativ!
>
> Natürlich kann das passieren, wenn Du char als Type verwendest. Das hat
> aber nichts mit getchar() zu tun.

Das war was anderes. Den Fehler mache ich definitiv nie. War wohl das 
Zeichen positiv, aber die Zeichenkonstante negativ.

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


Lesenswert?

Daniel A. schrieb:
> Da nimmt man extra '' für Zeichen im Switch, und dann sind die negativ!

Ja, Du hast 0x80 durch die Hochkommas in einen (negativen) char 
gewandelt.

Hier sieht man das ganz gut:
1
#include <stdio.h>
2
int main(int argc, char** argv)
3
{
4
    printf("%d %d\n", '\x80', 0x80);
5
}
1
$ cc a.c && ./a.out
2
-128 128

: Bearbeitet durch Moderator
von Daniel A. (daniel-a)


Lesenswert?

'\x80' ist aber vom type int: https://godbolt.org/z/Y5rj6Pq3G
1
#include <stdio.h>
2
3
int main(int argc, char** argv){
4
    printf("%zu %s\n", sizeof('\x80'), _Generic('\x80', char: "char", int: "int"));
5
}
Ausgabe:
1
4 int

von Udo K. (udok)


Lesenswert?

Frank M. schrieb:
> Bei ISO8859 funktioniert das durchaus. c hat dann nämlich einen
> positiven Wert, nämlich 0xE4 - auch wenn auf dem System char signed
> wäre. Beachte, dass Du "int c" geschrieben hast, nicht "char c".

Mein Verständnis ist: Char 'ä' ist signed ((char)0xE4 < 0), und wird 
implizit auf int gewandelt, damit habe ich eine negative Zahl.  Der 
Rückgabewert von getchar ist aber immer positiv oder -1.  Der Vergleich 
wird also schiefgehen.
Aber für ASCII Zeichen, die ja alle positiv sind, passt die Funktion. 
Negative Zeichenkonstanten muss man auf (unsigned char)'ä' wandeln.
Das kommt aber in der Praxis selten vor.

: Bearbeitet durch User
von Bruno V. (bruno_v)


Lesenswert?

Udo K. schrieb:
> Mein Verständnis ist: Char 'ä' ist signed ((char)0xE4 < 0), und wird
> implizit auf int gewandelt, damit habe ich eine negative Zahl.  D

"Hällo" ist ein char Array. Und dort kann das zweite Element negativ 
oder positiv sein (halt wie char implementiert ist, als signed oder 
unsigned)

'ä' ist ein integer. Und positiv, wenn es "im erweiterten ASCII" liegt.

Wenn ich 'a' nun einem char zuweise, dann wird es in diesem char halt 
als signed oder unsigned interpretiert, aber erst dort.

von Rolf M. (rmagnus)


Lesenswert?

Frank M. schrieb:
> Rolf M. schrieb:
>> Was überaus ungeschickt gemacht ist, denn char kann auch signed sein,
>> also einen Wertebereich von -0x80 bis 0x7F haben.
>
> Der Return-Wert von getchar() ist int. Schon der erste Kernighan-Ritchie
> benutzte  int c = getchar();

Ja, das ist auch der korrekte Weg.

Wf88 schrieb:
> Udo K. schrieb:
>> 'ä'
>
> Weil für ein 'ä' brauchst du anderes Charset als das default.

Frank M. schrieb:
> Rolf M. schrieb:
>> Was überaus ungeschickt gemacht ist, denn char kann auch signed sein,
>> also einen Wertebereich von -0x80 bis 0x7F haben.
>
> Dieser bezog sich auf getchar(). Und darauf habe ich geantwortet. Dass
> Du jetzt darauf ansprichst, weil Du mal den Fehler gemacht hast, einen
> signed char buffer zu verwenden, hat mit getchar() überhaupt nichts zu
> tun.
>
> Wenn Du Zeichen speichern(!) willst, dann natürlich unsigned char:

Wie "natürlich"? Der Typ für Text ist char. Alle Stringfunktionen wie 
printf() oder strcmp() arbeiten mit Arrays aus char, nicht aus unsigned 
char. Explizit sollte man die signedness nur angeben, wenn man damit 
rechnen oder Bitgefummel machen will, denn Text hat eigentlich keine 
Signedness.

> Aber zum Auswerten des Rückgabewertes von getchar() brauchst Du
> weiterhin ein int!

Ja. Das Problem ist: char ist eigentlich der Texttyp. Wenn der signed 
ist, dann muss getchar() den Wert erst in einen unsigned char wandeln, 
was auch im Standard so steht. Spannender wird es z.B. bei toupper(). 
Sagen wir mal, ich möchte mit fgets() (das auch mit einem char* 
arbeitet) einen String einlesen und diesen dann per toupper() 
zeichenweise in Großbuchstaben wandeln:
1
char c[100];
2
fgets(c, 100, stdin);
3
for (size_t i = 0; c[i] != '\0'; ++i)
4
    c[i] = toupper(c[i]); // undefined behavior!
An toupper() dürfen nämlich außer EOF keine negativen Werte übergeben 
werden. Man muss erst nach unsigned char casten.

Frank M. schrieb:
> Daniel A. schrieb:
>> Ich hab gerade nochmal nachgesehen, was der Standard sagt. Die Zeichen
>> die getchar zurückgibt sind tatsächlich als ob sie vorher nach unsigned
>> char konvertiert wurden.
>> Und EOF muss negativ sein, aber es muss nicht zwingend -1 sein.
>
> Eben.

Und genau das ist es, was ich meinte.

Udo K. schrieb:
> Frank M. schrieb:
>> Bei ISO8859 funktioniert das durchaus. c hat dann nämlich einen
>> positiven Wert, nämlich 0xE4 - auch wenn auf dem System char signed
>> wäre. Beachte, dass Du "int c" geschrieben hast, nicht "char c".
>
> Mein Verständnis ist: Char 'ä' ist signed ((char)0xE4 < 0), und wird
> implizit auf int gewandelt,

In C ist 'ä' bereits vom Typ int. In C++ ist es vom Typ char, muss aber 
so wie du sagst für den Vergleich erst nach int konvertiert werden 
(Integer-Promotion).

> damit habe ich eine negative Zahl.  Der Rückgabewert von getchar ist aber
> immer positiv oder -1.  Der Vergleich wird also schiefgehen.

Das ist richtig.

> Aber für ASCII Zeichen, die ja alle positiv sind, passt die Funktion.
> Negative Zeichenkonstanten muss man auf (unsigned char)'ä' wandeln.

Oder halt umgekehrt den Rückgabewert von getchar() nach char wandeln.

> Das kommt aber in der Praxis selten vor.

Heutzutage mit UTF-8 gibt's kein 'ä' mehr.

Bruno V. schrieb:
> 'ä' ist ein integer. Und positiv, wenn es "im erweiterten ASCII" liegt.

Nein, eben nicht. Wenn char signed ist, ist 'ä' ein int mit negativem 
Wert!

: Bearbeitet durch User
von Bruno V. (bruno_v)


Lesenswert?

Rolf M. schrieb:
> Wenn char signed ist, ist 'ä' ein int mit negativem Wert!

Ups, ja.

von Bauform B. (bauformb)


Lesenswert?

Was haltet ihr von -funsigned-char?

von Wf88 (wf88)


Lesenswert?

Bauform B. schrieb:
> Was haltet ihr von -funsigned-char?

Nicht allzuviel, ich hab gern "selbst" (=direkt im Code) in der Hand, 
was ich mit einer Variablen mache, bzw wie diese interpretiert wird.

Vielleicht habe ich den Sinn dieses Parameters aber auch nicht ganz 
verstanden, keine Ahnung...

von Rolf M. (rmagnus)


Lesenswert?

Der C-Standard sagt, dass es alle Integer-Typen in einer signed- und 
einer unsigned-Variante gibt. Dabei gilt, dass der Default, wenn man 
nichts explizit angibt, immer signed ist - außer für char. Da ist es 
implementation-defined, also der Compiler darf das entscheiden.
Aus Gründen der Konsistenz mit den anderen Integer-Typen ist char 
deshalb zumindest bei gcc meist signed.
Da es aber eben compilerabhängig ist, sollte an sich die Verwendung am 
besten so sein:

signed char   - für einen kleinen Integer mit Vorzeichen
unsigned char - für einen kleinen Integer ohne Vorzeichen
char          - für Text

Allerdings scheinen manche ein Problem damit zu haben, wenn Textzeichen 
in einem signed-Typ gespeichert werden, obwohl das streng genommen egal 
sein sollte. Text braucht nur genug Bits, um ein Zeichen zu speichern. 
Wie diese Bits verwendet würden, wenn man damit rechnen würde, spielt ja 
keine Rolle. Auf der anderen Seite sind dann noch die oben genannten 
Funktionen, die wie schon gesagt eher ungeschickt definiert sind und 
nicht sonderlich gut zu einem signed-char passen. Daher wird der eine 
oder andere mit dieser Option char auf unsigned zwingen.
Am Ende schreibe ich aber meine Programme lieber so, dass es keine Rolle 
spielt, ob char signed oder unsigned ist und damit auch dieser 
Kommandozeilenparameter überflüssig ist.

: Bearbeitet durch User
von Bruno V. (bruno_v)


Lesenswert?

Rolf M. schrieb:
> ohne Vorzeichen char - für Text

Ja. Es geht nicht um char als Variable (da kann ich ja vorschreiben, was 
ich will) sondern um Stringkonstanten und library-funktionen mit char. 
Da würden ja genug Beispiele genannt.

von Rolf M. (rmagnus)


Lesenswert?

Bruno V. schrieb:
> Es geht nicht um char als Variable (da kann ich ja vorschreiben, was
> ich will) sondern um Stringkonstanten und library-funktionen mit char.

Sinnigerweise sollten beide das gleiche verwenden.

von Richard (nbger)


Lesenswert?

Andreas B. schrieb:
> Ineffizient. Ein Byte oder ein Wort lesen, dann die anderen Bits
> ausmaskieren kostet Zeit und Code. Beim Schreiben genauso. Ausnahme: Der
> Prozessor hat entsprechende Bit-Befehle, etwa MSC-51 oder bei ARM
> Bitbanding. Letzteres wird aber nur stiefmütterlich unterstützt und ist
> (deshalb?) bei neueren Typen gar nicht mehr vorhanden.

C167 hatte auch Bitbefehle, da hätte das Sinn gemacht.
Ist schon so lange her...ich weiß nicht mehr, ob der C-Compiler diese 
Befehle genutzt hat.
Ansonsten ist die kleinste Zugriffseinheit bei den Prozessoren 1 Byte, 1 
Wort, 1 Doppelwort usw...., abhängig von der Breite des Datenbus.
Wie Andreas schrieb, würde es Code und Zeit kosten die Bits innerhalb 
eines Bytes zu maskieren.
bool macht trotzdem Sinn in C:
FALSE = 0; TRUE = !FALSE (also alles außer 0)

von Bruno V. (bruno_v)


Lesenswert?

Richard R. schrieb:
> bool macht trotzdem Sinn in C:
> FALSE = 0; TRUE = !FALSE (also alles außer 0)

Wenn es als Scherz gemeint ist, dann bitte Smiley ;-)

TRUE ist hier 1. '!' bedeutet nicht "alles außer" sondern "0-->1, sonst 
-->0"

von Rolf M. (rmagnus)


Lesenswert?

Bruno V. schrieb:
> Richard R. schrieb:
>> bool macht trotzdem Sinn in C:
>> FALSE = 0; TRUE = !FALSE (also alles außer 0)
>
> Wenn es als Scherz gemeint ist, dann bitte Smiley ;-)
>
> TRUE ist hier 1. '!' bedeutet nicht "alles außer" sondern "0-->1, sonst
> -->0"

Ja, den Fehler sieht man erstaunlich häufig. x != 0 ist aber eben nicht 
das gleiche wie x == !0.

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.