Die interessantere Frage hier wäre, warum diese Implementierung “inkonsistent” ist, da sie offensichtlich definiert _Bool Größe 1 zu haben, aber nicht true und false. Aber dazu sagt die Norm meines Wissens nichts.
– Benutzer2371524
30. Oktober 2017 um 9:02 Uhr
@FelixPalmen derselbe Grund, warum angegeben char a;sizeof(a) == 1 und sizeof('a') == sizeof(int) (in C). Es geht nicht um die Umsetzung, sondern um die Sprache.
– n. 1.8e9-wo-ist-meine-Aktie m.
30. Oktober 2017 um 9:12 Uhr
Haben Sie versucht zu drucken sizeof(true)? vielleicht wird es etwas klarer (insbesondere wird deutlich, dass der ternäre Operator ein Ablenkungsmanöver ist).
– n. 1.8e9-wo-ist-meine-Aktie m.
30. Oktober 2017 um 9:17 Uhr
@FelixPalmen true ist #defined zu 1 durch sein stdbool.h Also ja, das ist die wörtliche Definition.
– n. 1.8e9-wo-ist-meine-Aktie m.
30. Oktober 2017 um 9:29 Uhr
Es ist, weil Sie haben #include <stdbool.h>. Diese Überschrift definiert Makrostrue und false sein 1 und 0also sieht deine Aussage so aus:
printf("%zu\n", sizeof(a ? 1 : 0)); // Why 4?
sizeof(int) ist 4 auf Ihrer Plattform.
„Das liegt daran, dass Sie #include haben.“ Nein, ist es nicht. sizeof(a ? (uint8_t)1 : (uint8_t)0); würde auch ein Ergebnis von 4 ergeben. Die Integer-Promotion des ?: Operanden ist hier der wichtige Teil, nicht die Größe true und false.
– Ludin
31. Oktober 2017 um 9:14 Uhr
@Lundin: Beides ist wichtig. Wie geschrieben steht der Typ schon int ohne Förderung. Der Grund, warum Sie es nicht “reparieren” können, sind die Standardaktionen.
– R.. GitHub HÖR AUF, EIS ZU HELFEN
31. Oktober 2017 um 16:28 Uhr
@PeterSchneider Das ist nicht C++. Das ist C. In C++ true und false sind nicht Makros; sie sind Schlüsselwörter. Sie sind nicht so definiert 1 und 0sondern die wahren und falschen Werte von sein bool Typ.
– Justin
31. Oktober 2017 um 18:49 Uhr
@PeterSchneider Nein, du hast heute etwas über C gelernt. Verwechseln Sie die beiden Sprachen nicht. In C++, sizeof(true) ist 1. Demo.
– Rakete1111
31. Oktober 2017 um 18:52 Uhr
Richtig, verwechselt. Hatte nicht sorgfältig gelesen und wurde von cppreference-link in die Irre geführt. Meine Schuld, danke. Aber dieses Gefühl habe ich bei c++ sowieso.
– Peter Schneider
31. Oktober 2017 um 18:56 Uhr
Sourav Ghosh
Hier ternäre Operatorrückgabe boolean Typ,
Okay, da ist noch mehr!
In C das Ergebnis von Dies ternärer Betrieb ist vom Typ int. [notes below (1,2)]
Daher ist das Ergebnis dasselbe wie der Ausdruck sizeof(int)auf Ihrer Plattform.
Anmerkung 1: Zitieren C11Kapitel §7.18, Boolean type and values <stdbool.h>
[….] Die verbleibenden drei Makros eignen sich für die Verwendung in #if Vorverarbeitungsanweisungen. Sie sind
true
die zur ganzzahligen Konstante 1 erweitert wird,
false
die zur ganzzahligen Konstante 0 erweitert wird, [….]
Hinweis 2: Für Bedingungsoperator, Kapitel §6.5.15, (Betonung von mir)
Der erste Operand wird ausgewertet; Es gibt einen Sequenzpunkt zwischen seiner Auswertung und der Auswertung des zweiten oder dritten Operanden (je nachdem, welcher ausgewertet wird). Der zweite Operand wird nur ausgewertet, wenn der erste ungleich 0 ist; der dritte Operand wird nur ausgewertet, wenn der erste gleich 0 ist; das Ergebnis ist der Wert des zweiten oder dritten Operanden (je nachdem, was ausgewertet wird), […]
und
Wenn sowohl der zweite als auch der dritte Operand einen arithmetischen Typ haben, ist der Ergebnistyp, der durch die üblichen arithmetischen Konvertierungen bestimmt würde, wenn sie auf diese beiden Operanden angewendet würden, der Typ des Ergebnisses. [….]
daher ist das Ergebnis vom Typ Integer und aufgrund des Wertebereichs sind die Konstanten genau vom Typ int.
Das heißt, ein allgemeiner Rat, int main() sollte besser sein int main (void) wirklich standardkonform zu sein.
@user694733 ähm..warum nicht? <stdbool.h> definiert die MACROS als vom Typ int..ist das falsch?
– Sourav Ghosh
30. Oktober 2017 um 8:44 Uhr
@BasileStarynkevitch OK, ich sehe das jetzt, das scheint in der Tat falsch zu sein, jetzt aktualisiert.
– Sourav Ghosh
30. Oktober 2017 um 8:48 Uhr
n. 1.8e9-wo-ist-meine-Aktie m.
Der ternäre Operator ist ein Ablenkungsmanöver.
printf("%zu\n", sizeof(true));
druckt 4 (oder was auch immer sizeof(int) befindet sich auf Ihrer Plattform).
Das Folgende geht davon aus bool ist ein Synonym für char oder ein ähnlicher Typ der Größe 1 und int ist größer als char.
Der Grund warum sizeof(true) != sizeof(bool) und sizeof(true) == sizeof(int) liegt einfach daran true ist nicht ein Ausdruck des Typs bool. Es ist ein Ausdruck des Typs int. es ist #defined wie 1 in stdbool.h.
Es gibt keine rvalues vom Typ bool überhaupt in C. Jeder solche rvalue wird sofort zu befördert intauch wenn es als Argument für verwendet wird sizeof. Bearbeiten: Dieser Absatz ist nicht wahr, Argumente dazu sizeof nicht befördert werden int. Dies hat jedoch keinen Einfluss auf die Schlussfolgerungen.
Gute Antwort. Nachdem ich die derzeit am meisten positiv bewertete Antwort gelesen hatte, dachte ich, dass alle Aussagen mit 4 bewertet werden sollten. Dies klärte die Dinge auf. +1
– Pedro A
30. Oktober 2017 um 11:58 Uhr
Ist nicht (bool)1 ein rvalue vom Typ bool?
– Ben Voigt
30. Oktober 2017 um 19:53 Uhr
printf("%u\n", sizeof((char) 1)); Drucke 1 auf meiner Plattform während printf("%u\n", sizeof(1)); Drucke 4. Bedeutet dies nicht, dass Ihre Aussage “Jeder solche rvalue wird sofort zu int hochgestuft, auch wenn er als Argument für sizeof verwendet wird” falsch ist?
– JonatanE
31. Oktober 2017 um 7:48 Uhr
Das beantwortet die Frage nicht wirklich. Größe und Art der true usw. ist im Fall von nicht wirklich wichtig ?: da es ganzzahlig befördert wird int jedenfalls. Das heißt, die Antwort sollte ansprechen warum?: ist ein roter Hering.
– Ludin
31. Oktober 2017 um 9:12 Uhr
Ich denke, die Antwort spricht das Problem auf die bestmögliche Weise an. Sie können es gerne ablehnen oder verbessern.
– n. 1.8e9-wo-ist-meine-Aktie m.
31. Oktober 2017 um 9:46 Uhr
Lundin
Bezüglich des booleschen Typs in C
Ein boolescher Typ wurde ziemlich spät in der Sprache C eingeführt, im Jahr 1999. Davor hatte C keinen booleschen Typ, sondern verwendet int für alle booleschen Ausdrücke. Daher alle logischen Operatoren wie z > == ! etc zurück an int von Wert 1 oder 0.
Für Anwendungen war es üblich, hausgemachte Typen wie z typedef enum { FALSE, TRUE } BOOL;was auch darauf hinausläuft int-große Typen.
C++ hatte einen viel besseren und expliziteren booleschen Typ, bool, die nicht größer als 1 Byte war. Während die booleschen Typen oder Ausdrücke in C im schlimmsten Fall als 4 Bytes enden würden. Eine gewisse Kompatibilität mit C++ wurde in C mit dem C99-Standard eingeführt. C bekam dann einen booleschen Typ _Bool und auch die Überschrift stdbool.h.
stdbool.h bietet eine gewisse Kompatibilität mit C++. Dieser Header definiert das Makro bool (gleiche Schreibweise wie das C++-Schlüsselwort), das erweitert wird zu _Bool, ein Typ, der ein kleiner ganzzahliger Typ ist, wahrscheinlich 1 Byte groß. In ähnlicher Weise stellt der Header zwei Makros bereit true und falsegleiche Schreibweise wie C++-Schlüsselwörter, aber mit Abwärtskompatibilität zu älteren C-Programmen. Deswegen true und false erweitern zu 1 und 0 in C und ihr Typ ist int. Diese Makros sind eigentlich nicht vom booleschen Typ, wie es die entsprechenden C++-Schlüsselwörter wären.
In ähnlicher Weise werden aus Gründen der Abwärtskompatibilität logische Operatoren in C still Rückkehr ein int bis heute, obwohl C heutzutage einen booleschen Typ hat. In C++ geben logische Operatoren a zurück bool. Also ein Ausdruck wie sizeof(a == b) gibt die Größe von an int in C, aber die Größe von a bool in C++.
Apropos Bedingungsoperator ?:
Der Bedingungsoperator ?: ist ein seltsamer Operator mit ein paar Macken. Es ist ein häufiger Fehler zu glauben, dass es zu 100% gleichwertig ist if() { } else {}. Nicht ganz.
Zwischen der Auswertung des 1. und des 2. bzw. 3. Operanden liegt ein Sequenzpunkt. Das ?: -Operator wertet garantiert nur den 2. oder 3. Operanden aus, sodass er keine Seiteneffekte des nicht ausgewerteten Operanden ausführen kann. Code wie true? func1() : func2() wird nicht ausgeführt func2(). So weit, ist es gut.
Jedochgibt es eine Sonderregel, die besagt, dass der 2. und 3. Operand implizit typaufgestuft und mit dem gegeneinander abgeglichen werden müssen übliche arithmetische Umrechnungen. (Implizite Heraufstufungsregeln in C werden hier erklärt). Das heißt, der 2. oder 3. Operand wird stets mindestens so groß wie ein sein int.
Das ist also egal true und false zufällig vom Typ sein int in C, weil der Ausdruck immer mindestens die Größe von an geben würde int egal.
Auch wenn Sie den Ausdruck umschreiben würdensizeof(a ? (bool)true : (bool)false)es würde immer noch die Größe von an zurückgebenint!
Dies liegt an der impliziten Typumwandlung durch die üblichen arithmetischen Konvertierungen.
chqrlie
Schnelle Antwort:
sizeof(a ? true : false) wertet zu 4 Weil true und false sind darin definiert <stdbool.h> wie 1 und 0 bzw. erweitert sich der Ausdruck zu sizeof(a ? 1 : 0) Dies ist ein ganzzahliger Ausdruck mit Typ int, das auf Ihrer Plattform 4 Bytes belegt. Aus dem gleichen Grunde, sizeof(true) würde auch zu bewerten 4 auf Ihrem System.
Beachten Sie jedoch Folgendes:
sizeof(a ? a : a) wertet auch aus 4 weil der ternäre Operator die ganzzahligen Heraufstufungen an seinem zweiten und dritten Operanden durchführt, wenn es sich um ganzzahlige Ausdrücke handelt. Dasselbe gilt natürlich auch für sizeof(a ? true : false) und sizeof(a ? (bool)true : (bool)false)aber Casting des gesamten Ausdrucks als bool verhält sich wie erwartet: sizeof((bool)(a ? true : false)) -> 1.
Beachten Sie auch, dass Vergleichsoperatoren zu booleschen Werten ausgewertet werden 1 oder 0aber haben int Typ: sizeof(a == a) -> 4.
Die einzigen Operatoren, die die boolesche Natur von beibehalten a wäre:
der Kommaoperator: beides sizeof(a, a) und sizeof(true, a) auswerten zu 1 zur Kompilierzeit.
die Zuweisungsoperatoren: beide sizeof(a = a) und sizeof(a = true) einen Wert von haben 1.
die Inkrementoperatoren: sizeof(a++) -> 1
Schließlich gilt alles Obige nur für C: C++ hat eine andere Semantik in Bezug auf die bool Typ, boolesche Werte true und falseVergleichsoperatoren und der ternäre Operator: all dies sizeof() Ausdrücke werden ausgewertet 1 in C++.
Gute Antwort, die tatsächlich darauf hinweist, dass es nicht wirklich darauf ankommt, welcher Typ true und false sind, weil die ?: Operanden würden zur Ganzzahl befördert werden int jedenfalls. Daher sizeof(a ? (uint8_t)true : (uint8_t)false) ergibt auch 4 als Ergebnis.
– Ludin
31. Oktober 2017 um 9:10 Uhr
Diese Antwort deckt den wichtigsten wichtigen Punkt ab, nämlich den Wert, zu dem man befördert wird int
– Chinni
31. Oktober 2017 um 19:52 Uhr
asio_kerl
Hier ist ein Ausschnitt aus dem, was in der Quelle enthalten ist
Es Makros true und false werden als 1 bzw. 0 deklariert.
In diesem Fall ist der Typ jedoch der Typ der Literalkonstanten. Sowohl 0 als auch 1 sind ganzzahlige Konstanten, die in ein int passen, also ist ihr Typ int.
und die sizeof(int) in Ihrem Fall ist 4.
Gute Antwort, die tatsächlich darauf hinweist, dass es nicht wirklich darauf ankommt, welcher Typ true und false sind, weil die ?: Operanden würden zur Ganzzahl befördert werden int jedenfalls. Daher sizeof(a ? (uint8_t)true : (uint8_t)false) ergibt auch 4 als Ergebnis.
– Ludin
31. Oktober 2017 um 9:10 Uhr
Diese Antwort deckt den wichtigsten wichtigen Punkt ab, nämlich den Wert, zu dem man befördert wird int
– Chinni
31. Oktober 2017 um 19:52 Uhr
Khaled.K
Es gibt keinen booleschen Datentyp in C, stattdessen werden logische Ausdrücke zu ganzzahligen Werten ausgewertet 1 wenn es sonst wahr ist 0.
Bedingte Ausdrücke wie if, for, whileoder c ? a : b Erwarten Sie eine Ganzzahl, wenn die Zahl nicht Null ist, wird sie berücksichtigt true Abgesehen von einigen Sonderfällen ist hier eine rekursive Summenfunktion, in der der ternäre Operator ausgewertet wird true bis um n erreichen 0.
int sum (int n) { return n ? n+sum(n-1) : n ;
Es kann auch verwendet werden NULL check a pointer, hier ist eine rekursive Funktion, die den Inhalt einer Single-Linked-List ausgibt.
sizeof(true)
undsizeof(false)
ist auch 4: ide.geeksforgeeks.org/O5jvuN– tkausl
30. Oktober 2017 um 8:40 Uhr
Die interessantere Frage hier wäre, warum diese Implementierung “inkonsistent” ist, da sie offensichtlich definiert
_Bool
Größe 1 zu haben, aber nichttrue
undfalse
. Aber dazu sagt die Norm meines Wissens nichts.– Benutzer2371524
30. Oktober 2017 um 9:02 Uhr
@FelixPalmen derselbe Grund, warum angegeben
char a;
sizeof(a) == 1
undsizeof('a') == sizeof(int)
(in C). Es geht nicht um die Umsetzung, sondern um die Sprache.– n. 1.8e9-wo-ist-meine-Aktie m.
30. Oktober 2017 um 9:12 Uhr
Haben Sie versucht zu drucken
sizeof(true)
? vielleicht wird es etwas klarer (insbesondere wird deutlich, dass der ternäre Operator ein Ablenkungsmanöver ist).– n. 1.8e9-wo-ist-meine-Aktie m.
30. Oktober 2017 um 9:17 Uhr
@FelixPalmen
true
ist#define
d zu 1 durch seinstdbool.h
Also ja, das ist die wörtliche Definition.– n. 1.8e9-wo-ist-meine-Aktie m.
30. Oktober 2017 um 9:29 Uhr