Also, wenn ich es gut verstanden habe, sieht integrale Werbung Folgendes vor: char, wchar_t, bool, enum, short
-Typen werden IMMER in int
(oder unsigned int
) konvertiert. Wenn dann in einem Ausdruck verschiedene Typen vorhanden sind, wird eine weitere Konvertierung angewendet.
Verstehe ich das gut?
Und wenn ja, dann meine Frage: Warum ist es gut? Warum? Werden Sie char/wchar_t/bool/enum/short
nicht unnötig? Ich meine zum Beispiel:
Wie ich zuvor beschrieben habe, wird char
ALWAYS in int
konvertiert, also sieht dies in diesem Fall nach der automatischen Konvertierung folgendermaßen aus:
Aber ich kann nicht verstehen, warum das gut ist, wenn ich weiß, dass char
type genug für meine Bedürfnisse ist.
Die Conversions, nach denen Sie fragen, sind die üblichen arithmetischen Conversions und die Integer-Promotions , die in Abschnitt 6.3.1.8 des neuesten ISO C-Standards definiert sind. Sie werden auf die Operanden der meisten binären Operatoren angewendet ("binary" bedeutet, dass sie zwei Operanden benötigen, z. B. +
, *
usw.). (Die Regeln sind für C ++ ähnlich. In dieser Antwort werde ich nur auf den C-Standard verweisen.)
Kurz gesagt sind die üblichen arithmetischen Konvertierungen :
long double
ist, wird der andere Operand in long double
konvertiert. double
ist, wird der andere Operand in double
konvertiert. float
ist, wird der andere Operand in float
konvertiert. Die Integer-Promotions sind in Abschnitt 6.3.1.1 des C-Standards definiert. Für einen Typ, der enger als int
ist, wenn der Typ int
alle Werte des Typs enthalten kann, wird ein Ausdruck dieses Typs in int
; Andernfalls wird es in unsigned int
konvertiert. (Beachten Sie, dass ein Ausdruck vom Typ unsigned short
abhängig von den relativen Bereichen der Typen in int
oder in unsigned int
konvertiert werden kann.)
Die Integer-Aktionen werden auch auf Funktionsargumente angewendet, wenn die Deklaration den Typ des Parameters nicht angibt. Zum Beispiel:
%Vor% fördert den short
-Wert auf int
. Diese Aktion tritt nicht für nicht-variadische Funktionen auf.
Die schnelle Antwort dafür, warum dies getan wird, ist, dass der Standard dies sagt.
Der Grund für all diese Komplexität liegt in der eingeschränkten Menge von arithmetischen Operationen, die auf den meisten CPUs verfügbar sind. Bei diesem Regelwerk müssen alle arithmetischen Operatoren (mit Ausnahme der Shift-Operatoren, die ein Sonderfall sind) nur an Operanden desselben Typs arbeiten. Es gibt keinen short + long
Additionsoperator; stattdessen wird der Operand short
implizit in long
konvertiert. Und es gibt keine arithmetischen Operatoren für engere Typen als int
; Wenn Sie zwei short
-Werte hinzufügen, werden beide Argumente auf int
hochgestuft, was zu einem int
-Ergebnis führt (das dann möglicherweise wieder in short
konvertiert wird).
Einige CPUs können arithmetische Operationen an schmalen Operanden durchführen, aber nicht alle können dies tun. Ohne diesen einheitlichen Satz von Regeln müssten entweder Compiler eine enge Arithmetik auf CPUs emulieren, die sie nicht direkt unterstützen, oder das Verhalten von arithmetischen Ausdrücken würde je nachdem variieren Operationen, die die Ziel-CPU unterstützt. Die aktuellen Regeln sind ein guter Kompromiss zwischen der Konsistenz zwischen den Plattformen und der guten Nutzung der CPU-Operationen.
Wenn ich es gut verstanden habe, liefert integral promotion Folgendes: char, wchar_t, bool, enum, kurze Typen, die IMMER in int (oder unsigned int) konvertiert werden.
Ihr Verständnis ist nur teilweise richtig: Kurze Typen werden tatsächlich zu int
befördert, aber nur, wenn Sie sie in Ausdrücken verwenden. Die Konvertierung erfolgt unmittelbar vor der Nutzung. Es wird auch "rückgängig gemacht", wenn das Ergebnis gespeichert wird.
Die Art und Weise, wie die Werte gespeichert werden, bleibt mit den Eigenschaften des Typs konsistent, sodass Sie steuern können, wie Sie Ihren Speicher für die von Ihnen gespeicherten Variablen verwenden. Zum Beispiel
%Vor%ist viermal so klein wie
%Vor% auf Systemen mit 32-Bit int
s.
Die Konvertierung wird nicht ausgeführt, wenn Sie den Wert in der Variablen speichern. Die Konvertierung wird ausgeführt, wenn Sie den Wert umwandeln oder wenn Sie eine Operation wie eine arithmetische Operation explizit ausführen
Es hängt wirklich von Ihrer zugrundeliegenden Mikroprozessorarchitektur ab. Wenn Ihr Prozessor beispielsweise 32-Bit ist, ist dies die native Integer-Größe. Die Verwendung der nativen Integer-Größe in Integer-Berechnungen ist besser optimiert.
Die Typumwandlung findet statt, wenn arithmetische Operationen, Verschiebeoperationen, unäre Operationen ausgeführt werden. Sehen Sie, welcher Standard dazu sagt:
Wenn ein
int
alle Werte des ursprünglichen Typs darstellen kann (wie durch die Breite beschränkt, für a Bit-Feld), wird der Wert in einin
t umgewandelt; Andernfalls wird es in einunsigned int
konvertiert. Diese werden als Integer - Promotions .58 bezeichnet. Alle anderen Typen werden von der ganzzahlige Werbeaktionen58. Die Integer-Promotions werden nur angewendet: als Teil der üblichen arithmetischen Konvertierungen, für bestimmte Argumentausdrücke, für die Operanden der unären Operatoren
+
,-
und~
und bis beide Operanden der Shift-Operatoren , 1 wie in ihren jeweiligen Unterklauseln angegeben
1. Der Schwerpunkt liegt bei mir.
Tags und Links c c++ integer-promotion