Implicit conversions
Wenn ein Ausdruck in einem Kontext verwendet wird, in dem ein Wert eines anderen Typs erwartet wird, Konvertierung kann auftreten:
int n = 1L; // Ausdruck 1L hat Typ long, int wird erwartet n = 2.1; // Ausdruck 2.1 hat Typ double, int wird erwartet char* p = malloc(10); // Ausdruck malloc(10) hat Typ void*, char* wird erwartet
Konvertierungen finden in den folgenden Situationen statt:
Konvertierung wie durch Zuweisung
- Im Zuweisungsoperator wird der Wert des rechten Operanden in den uneingeschränkten Typ des linken Operanden konvertiert.
- Bei der Skalarinitialisierung wird der Wert des Initialisierungsausdrucks in den uneingeschränkten Typ des zu initialisierenden Objekts konvertiert.
- In einem Funktionsaufrufausdruck , an eine Funktion mit Prototyp, wird der Wert jedes Argumentausdrucks in den Typ der uneingeschränkten deklarierten Typen des entsprechenden Parameters konvertiert.
- In einer return-Anweisung wird der Wert des Operanden von return in ein Objekt mit dem Rückgabetyp der Funktion konvertiert.
Beachten Sie, dass die tatsächliche Zuweisung zusätzlich zur Konvertierung auch überflüssigen Bereich und Präzision von Gleitkommatypen entfernt und Überlappungen verbietet; diese Eigenschaften gelten nicht für die Konvertierung wie durch Zuweisung.
Standardargument-Promotionen
In einem Funktionsaufrufausdruck wenn der Aufruf erfolgt an
Jedes Argument vom Ganzzahltyp durchläuft Integer-Promotion , und jedes Argument vom Typ float wird implizit zum Typ double konvertiert.
int add_nums(int count, ...); int sum = add_nums(2, 'c', true); // add_nums wird mit drei int-Werten aufgerufen: (2, 99, 1)
|
Beachten Sie, dass float complex und float imaginary in diesem Kontext nicht zu double complex und double imaginary heraufgestuft werden. |
(seit C99) |
Übliche arithmetische Konvertierungen
Die Argumente der folgenden arithmetischen Operatoren durchlaufen implizite Konvertierungen, um den gemeinsamen Realtyp zu erhalten, welcher der Typ ist, in dem die Berechnung durchgeführt wird:
- binäre Arithmetik * , / , % , + , - ,
- Vergleichsoperatoren < , > , <= , >= , == , ! = ,
- binäre bitweise Arithmetik & , ^ , | ,
- der bedingte Operator ?: .
|
1)
Wenn ein Operand Dezimal-Gleitkommatyp hat, darf der andere Operand keinen Standard-Gleitkommatyp,
komplexen oder imaginären Typ haben.
|
(seit C23) |
-
- Ganzzahl- oder Gleitkommatyp zu long double
| (seit C99) |
-
- Ganzzahl- oder Gleitkommatyp zu double
| (seit C99) |
-
- Ganzzahltyp zu float (der einzig mögliche reale Typ ist float, der unverändert bleibt)
| (seit C99) |
-
- Wenn die Typen identisch sind, ist dieser Typ der gemeinsame Typ.
-
Andernfalls sind die Typen unterschiedlich:
- Wenn die Typen die gleiche Vorzeichenbehaftung haben (beide vorzeichenbehaftet oder beide vorzeichenlos), wird der Operand, dessen Typ den geringeren Konvertierungsrang [1] hat, implizit konvertiert [2] in den anderen Typ.
-
Andernfalls haben die Operanden unterschiedliche Vorzeichenbehaftung:
- Wenn der vorzeichenlose Typ einen Konvertierungsrang größer oder gleich dem Rang des vorzeichenbehafteten Typs hat, dann wird der Operand mit dem vorzeichenbehafteten Typ implizit in den vorzeichenlosen Typ konvertiert.
-
Andernfalls hat der vorzeichenlose Typ einen
Konvertierungsrang
kleiner als der vorzeichenbehaftete Typ:
- Wenn der vorzeichenbehaftete Typ alle Werte des vorzeichenlosen Typs darstellen kann, dann wird der Operand mit dem vorzeichenlosen Typ implizit in den vorzeichenbehafteten Typ konvertiert.
- Andernfalls durchlaufen beide Operanden eine implizite Konvertierung in den vorzeichenlosen Gegenpart des Typs des vorzeichenbehafteten Operanden.
- ↑ Siehe Integer-Promotions unten für die Regeln zur Rangbestimmung.
- ↑ Siehe "Ganzzahlkonvertierungen" unter implizite Konvertierungssemantik unten.
1.f + 20000001; // int wird zu float konvertiert, ergibt 20000000.00 // Addition und anschließende Rundung auf float ergibt 20000000.00 (char)'a' + 1L; // zuerst wird char 'a', welches 97 ist, zu int heraufgestuft // verschiedene Typen: int und long // gleiche Vorzeichenbehaftung: beide vorzeichenbehaftet // unterschiedlicher Rang: long hat höheren Rang als int // daher wird int 97 zu long 97 konvertiert // das Ergebnis ist 97 + 1 = 98 vom Typ signed long 2u - 10; // verschiedene Typen: unsigned int und signed int // unterschiedliche Vorzeichenbehaftung // gleicher Rang // daher wird signed int 10 zu unsigned int 10 konvertiert // da die arithmetische Operation für vorzeichenlose Ganzzahlen durchgeführt wird // (siehe Thema "Arithmetische Operatoren"), wird die Berechnung (2 - 10) // modulo (2 hoch n) durchgeführt, wobei n die Anzahl der Wertbits von unsigned int ist // wenn unsigned int 32-Bit lang ist und keine Füllbits in seiner Objektdarstellung vorhanden sind // dann ist das Ergebnis (-8) modulo (2 hoch 32) = 4294967288 // vom Typ unsigned int 5UL - 2ULL; // verschiedene Typen: unsigned long und unsigned long long // gleiche Vorzeichenbehaftung // unterschiedlicher Rang: Rang von unsigned long long ist höher // daher wird unsigned long 5 zu unsigned long long 5 konvertiert // da die arithmetische Operation für vorzeichenlose Ganzzahlen durchgeführt wird // (siehe Thema "Arithmetische Operatoren"), // wenn unsigned long long 64-Bit lang ist, dann // ist das Ergebnis (5 - 2) modulo (2 hoch 64) = 3 vom Typ // unsigned long long 0UL - 1LL; // verschiedene Typen: unsigned long und signed long long // unterschiedliche Vorzeichenbehaftung // unterschiedlicher Rang: Rang von signed long long ist höher // wenn ULONG_MAX > LLONG_MAX, dann kann signed long long nicht alle // unsigned long Werte darstellen, daher ist dies der letzte Fall: beide Operanden werden // zu unsigned long long konvertiert unsigned long 0 wird zu unsigned long long 0 konvertiert // long long 1 wird zu unsigned long long 1 konvertiert da die arithmetische // Operation für vorzeichenlose Ganzzahlen durchgeführt wird // (siehe Thema "Arithmetische Operatoren"), // wenn unsigned long long 64-Bit lang ist, dann // ist die Berechnung (0 - 1) modulo (2 hoch 64) // somit ist das Ergebnis 18446744073709551615 (ULLONG_MAX) vom Typ // unsigned long long
|
Der Ergebnistyp wird wie folgt bestimmt:
double complex z = 1 + 2*I; double f = 3.0; z + f; // z remains as-is, f is converted to double, the result is double complex |
(seit C99) |
Wie immer kann das Ergebnis eines Gleitkomma-Operators einen größeren Bereich und höhere Genauigkeit haben als durch seinen Typ angegeben (siehe FLT_EVAL_METHOD ).
|
Hinweis: Reale und imaginäre Operanden werden nicht implizit in komplexe Zahlen konvertiert, da dies zusätzliche Berechnungen erfordern würde und in bestimmten Fällen mit Unendlichkeiten, NaNs und vorzeichenbehafteten Nullen unerwünschte Ergebnisse liefern könnte. Zum Beispiel würde 2.0×(3.0+i∞), wenn reale Zahlen in komplexe konvertiert würden, als (2.0+i0.0)×(3.0+i∞) ⇒ (2.0×3.0–0.0×∞) + i(2.0×∞+0.0×3.0) ⇒ NaN+i∞ ausgewertet werden, anstatt des korrekten 6.0+i∞. Wenn imaginäre Zahlen in komplexe konvertiert würden, würde i2.0×(∞+i3.0) als (0.0+i2.0) × (∞+i3.0) ⇒ (0.0×∞ – 2.0×3.0) + i(0.0×3.0 + 2.0×∞) ⇒ NaN + i∞ anstatt –6.0 + i∞ ausgewertet werden. |
(seit C99) |
Hinweis: Ungeachtet der üblichen arithmetischen Konvertierungen kann die Berechnung gemäß der as-if rule stets in einem schmaleren Typ durchgeführt werden, als durch diese Regeln spezifiziert.
Werttransformationen
Lvalue-Konvertierung
Jeder Lvalue-Ausdruck eines beliebigen Nicht-Array-Typs, wenn er in einem anderen Kontext als
- als Operand des Adressoperators (falls erlaubt),
- als Operand der Prä-/Post- Inkrement- und Dekrementoperatoren ,
- als linker Operand des Elementzugriffsoperators (Punkt-Operator),
- als linker Operand der Zuweisungs- und zusammengesetzten Zuweisungsoperatoren ,
-
als Operand von
sizeof,
unterliegt einer
Lvalue-Konvertierung
: Der Typ bleibt gleich, verliert jedoch
const
-/
volatile
-/
restrict
-Qualifizierer und
atomic
-Eigenschaften, falls vorhanden. Der Wert bleibt gleich, verliert jedoch seine Lvalue-Eigenschaften (die Adresse kann möglicherweise nicht mehr genommen werden).
Wenn der L-Wert einen unvollständigen Typ hat, ist das Verhalten undefiniert.
Wenn der L-Wert ein Objekt mit automatischer Speicherdauer bezeichnet, dessen Adresse niemals genommen wurde und das nicht initialisiert war (nicht mit einem Initialisierer deklariert und vor der Verwendung keine Zuweisung daran durchgeführt wurde), ist das Verhalten undefiniert.
Diese Konvertierung modelliert den Speicherzugriff des Wertes des Objekts von seinem Speicherort.
volatile int n = 1; int x = n; // Lvalue-Konvertierung auf n liest den Wert von n volatile int* p = &n; // Keine Lvalue-Konvertierung: liest nicht den Wert von n
Array-zu-Zeiger-Konvertierung
Jeder Lvalue-Ausdruck (bis C99) Ausdruck (seit C99) vom Typ Array , wenn verwendet in einem Kontext außerhalb von
- als Operand des Adressoperators ,
-
als Operand von
sizeof, -
als Operand von
typeofundtypeof_unqual(seit C23) , - als Zeichenkettenliteral verwendet für Array-Initialisierung ,
unterzieht sich einer Konvertierung zum Nicht-Lvalue-Zeiger auf sein erstes Element.
Wenn das Array als
register
deklariert wurde, ist das Verhalten undefiniert.
Ein Nicht-Lvalue-Array oder eines seiner Elemente , ist nicht zugreifbar (bis C99) , hat temporäre Lebensdauer (seit C99) .
int a[3], b[3][4]; int* p = a; /* Konvertierung zu &a[0] */ int (*q)[4] = b; /* Konvertierung zu &b[0] */ struct S { int a[1]; }; struct S f(void) { struct S result = {{0}}; /* {0} seit C99 */ return result; } void g(void) { int* p = f().a; /* Fehler bis C99; OK seit C99 */ int n = f().a[0]; /* Fehler bis C99; OK seit C99 */ f().a[0] = 13; /* Fehler bis C99; UB seit C99 */ (void)p, (void)n; } int main(void) { return 0; }
Funktions-zu-Zeiger-Konvertierung
Jeder Funktionsbezeichner-Ausdruck, wenn er in einem anderen Kontext als
- als Operand des Adressoperators ,
-
als Operand von
sizeof, -
als Operand von
typeofundtypeof_unqual(seit C23) ,
unterliegt einer Konvertierung zum Nicht-Lvalue-Zeiger auf die durch den Ausdruck bezeichnete Funktion.
int f(int); int (*p)(int) = f; // Konvertierung zu &f (***p)(1); // wiederholte Dereferenzierung zu f und Rückkonvertierung zu &f
Semantik impliziter Konvertierung
Implizite Konvertierung, ob wie durch Zuweisung oder eine übliche arithmetische Konvertierung , besteht aus zwei Stufen:
Kompatible Typen
Die Umwandlung eines Werts beliebigen Typs in einen beliebigen kompatiblen Typ ist immer ein No-Op und ändert die Darstellung nicht.
uint8_t (*a)[10]; // falls uint8_t ein Typedef für unsigned char ist unsigned char (*b)[] = a; // dann sind diese Zeigertypen kompatibel
Ganzzahlige Höherstufungen
Integer Promotion ist die implizite Konvertierung eines Werts eines beliebigen Ganzzahltyps mit Rang kleiner oder gleich dem Rang von int oder eines Bitfelds vom Typ _Bool (bis C23) bool (seit C23) , int , signed int , unsigned int , in den Wert vom Typ int oder unsigned int .
Wenn int den gesamten Wertebereich des ursprünglichen Typs (oder den Wertebereich des ursprünglichen Bitfelds) darstellen kann, wird der Wert in den Typ int konvertiert. Andernfalls wird der Wert in unsigned int konvertiert.
|
Der Wert aus einem Bitfeld eines bitgenauen Ganzzahltyps wird in den entsprechenden bitgenauen Ganzzahltyp konvertiert. Andernfalls sind bitgenaue Ganzzahltypen von den Ganzzahl-Höherwertigkeitsregeln ausgenommen. |
(seit C23) |
Integer-Promotions bewahren den Wert, einschließlich des Vorzeichens:
int main(void) { void f(); // alte Funktionsdeklaration // seit C23 hat void f(...) dasselbe Verhalten bezüglich Promotions char x = 'a'; // Integer-Konvertierung von int zu char f(x); // Integer-Promotion von char zurück zu int } void f(x) int x; {} // die Funktion erwartet int
rank oben ist eine Eigenschaft jedes integer type und ist wie folgt definiert:
|
8)
der Rang eines bitgenauen vorzeichenbehafteten Ganzzahltyps muss größer sein als der Rang jedes Standard-Ganzzahltyps mit geringerer Breite oder jedes bitgenauen Ganzzahltyps mit geringerer Breite.
9)
der Rang jedes bitgenauen Ganzzahltyps relativ zu einem erweiterten Ganzzahltyp derselben Breite ist implementierungsdefiniert.
|
(seit C23) |
Hinweis: Ganzzahlaufwertungen werden nur angewendet
- als Teil der üblichen arithmetischen Konvertierungen (siehe oben),
- als Teil der Standardargument-Promotions (siehe oben),
- für den Operanden der unären arithmetischen Operatoren + und - ,
- für den Operanden des unären bitweisen Operators ~ ,
- für beide Operanden der Schiebeoperatoren << und >> .
Boolesche KonvertierungEin Wert jedes skalaren Typs kann implizit konvertiert werden zu _Bool (bis C23) bool (seit C23) . Die Werte, die gleich einem ganzzahligen konstanten Ausdruck mit Wert Null sind (bis C23) Null (für arithmetische Typen), null (für Zeigertypen) sind oder den Typ nullptr_t haben (seit C23) , werden konvertiert zu 0 (bis C23) false (seit C23) , alle anderen Werte werden konvertiert zu 1 (bis C23) true (seit C23) . bool b1 = 0.5; // b1 == 1 (0.5 converted to int would be zero) bool b2 = 2.0*_Imaginary_I; // b2 == 1 (but converted to int would be zero) bool b3 = 0.0 + 3.0*I; // b3 == 1 (but converted to int would be zero) bool b4 = 0.0 / 0.0; // b4 == 1 (NaN does not compare equal to zero) bool b5 = nullptr; // b5 == 0 (since C23: nullptr is converted to false) |
(seit C99) |
Integer-Konvertierungen
Ein Wert jedes ganzzahligen Typs kann implizit in jeden anderen ganzzahligen Typ konvertiert werden. Außer in den Fällen, die durch die oben genannten Höherstufungen und booleschen Konvertierungen abgedeckt sind, gelten folgende Regeln:
- wenn der Zieltyp den Wert darstellen kann, bleibt der Wert unverändert,
-
andernfalls, wenn der Zieltyp vorzeichenlos ist, wird der Wert
2
b
, wobei b die Anzahl der Wertbits im Zieltyp ist, wiederholt vom Quellwert subtrahiert oder zu ihm addiert, bis das Ergebnis in den Zieltyp passt. Mit anderen Worten, vorzeichenlose Ganzzahlen implementieren Modulo-Arithmetik. - andernfalls, wenn der Zieltyp vorzeichenbehaftet ist, ist das Verhalten implementierungsdefiniert (was das Auslösen eines Signals beinhalten kann).
char x = 'a'; // int → char, Ergebnis unverändert unsigned char n = -123456; // Ziel ist unsigned, Ergebnis ist 192 (d.h. -123456+483*256) signed char m = 123456; // Ziel ist signed, Ergebnis ist implementierungsdefiniert assert(sizeof(int) > -1); // assert schlägt fehl: // operator > erfordert Konvertierung von -1 zu size_t, // Ziel ist unsigned, Ergebnis ist SIZE_MAX
Reale Gleitkomma-Ganzzahl-Konvertierungen
Ein endlicher Wert jedes reellen Gleitkommatyps kann implizit in jeden Ganzzahltyp konvertiert werden. Außer in den Fällen, die bereits durch die oben beschriebene boolesche Konvertierung abgedeckt sind, gelten folgende Regeln:
- Der Bruchteil wird verworfen (abgeschnitten in Richtung Null).
-
- Wenn der resultierende Wert durch den Zieltyp dargestellt werden kann, wird dieser Wert verwendet
- andernfalls ist das Verhalten undefiniert.
int n = 3.14; // n == 3 int x = 1e10; // undefiniertes Verhalten für 32-Bit int
Ein Wert jedes ganzzahligen Typs kann implizit in jeden Gleitkommatyp mit reellen Zahlen konvertiert werden.
- wenn der Wert exakt durch den Zieltyp dargestellt werden kann, bleibt er unverändert.
- wenn der Wert dargestellt werden kann, aber nicht exakt, ist das Ergebnis eine implementierungsdefinierte Wahl entweder des nächsthöheren oder nächstniedrigeren Wertes, obwohl bei IEEE-Arithmetik-Unterstützung auf den nächsten Wert gerundet wird. Es ist nicht spezifiziert, ob FE_INEXACT in diesem Fall ausgelöst wird.
- wenn der Wert nicht dargestellt werden kann, ist das Verhalten undefiniert, obwohl bei IEEE-Arithmetik-Unterstützung FE_INVALID ausgelöst wird und der Ergebniswert nicht spezifiziert ist.
Das Ergebnis dieser Konvertierung kann einen größeren Wertebereich und höhere Genauigkeit aufweisen, als der Zieltyp angibt (siehe FLT_EVAL_METHOD ).
Wenn Kontrolle über FE_INEXACT bei Gleitkomma-zu-Ganzzahl-Konvertierungen benötigt wird, können rint und nearbyint verwendet werden.
double d = 10; // d = 10.00 float f = 20000001; // f = 20000000.00 (FE_INEXACT) float x = 1 + (long long)FLT_MAX; // undefiniertes Verhalten
Konvertierungen von Gleitkommazahlen
Ein Wert jedes reellen Gleitkommatyps kann implizit in jeden anderen reellen Gleitkommatyp konvertiert werden.
- Wenn der Wert exakt durch den Zieltyp dargestellt werden kann, bleibt er unverändert.
- Wenn der Wert dargestellt werden kann, aber nicht exakt, ist das Ergebnis der nächsthöhere oder nächstniedrigere Wert (mit anderen Worten, die Rundungsrichtung ist implementierungsdefiniert), obwohl bei IEEE-Arithmetik die Rundung zur nächsten Zahl erfolgt.
-
Wenn der Wert nicht dargestellt werden kann, ist das Verhalten undefiniert
.Dieser Abschnitt ist unvollständig
Grund: Überprüfen Sie IEEE, ob eine entsprechend vorzeichenbehaftete Unendlichkeit erforderlich ist
Das Ergebnis dieser Konvertierung kann einen größeren Bereich und höhere Genauigkeit aufweisen, als der Zieltyp angibt (siehe FLT_EVAL_METHOD ).
double d = 0.1; // d = 0.1000000000000000055511151231257827021181583404541015625 float f = d; // f = 0.100000001490116119384765625 float x = 2 * (double)FLT_MAX; // undefiniert
Komplexe TypkonvertierungenEin Wert jedes komplexen Typs kann implizit in jeden anderen komplexen Typ konvertiert werden. Der Realteil und der Imaginärteil folgen einzeln den Konvertierungsregeln für die reellen Fließkommatypen. Imaginäre TypkonvertierungenEin Wert jedes imaginären Typs kann implizit in jeden anderen imaginären Typ konvertiert werden. Der Imaginärteil folgt den Konvertierungsregeln für die reellen Fließkommatypen. double imaginary d = 0.1*_Imaginary_I; float imaginary f = d; // f ist 0.100000001490116119384765625*I Real-Komplex-KonvertierungenEin Wert jedes reellen Fließkommatyps kann implizit in jeden komplexen Typ konvertiert werden.
Ein Wert jedes komplexen Typs kann implizit in jeden reellen Fließkommatyp konvertiert werden.
Hinweis: Bei der Komplex-zu-Real-Konvertierung wird ein NaN im Imaginärteil nicht an das Realergebnis weitergegeben. double complex z = 0.5 + 3*I; float f = z; // der Imaginärteil wird verworfen, f wird auf 0.5 gesetzt z = f; // setzt z auf 0.5 + 0*I Real-Imaginär-KonvertierungenEin Wert jedes imaginären Typs kann implizit in jeden reellen Typ (Ganzzahl oder Fließkomma) konvertiert werden. Das Ergebnis ist immer eine positive (oder vorzeichenlose) Null, außer wenn der Zieltyp _Bool (bis C23) bool (seit C23) ist, in welchem Fall die booleschen Konvertierungsregeln angewendet werden. Ein Wert jedes reellen Typs kann implizit in jeden imaginären Typ konvertiert werden. Das Ergebnis ist immer eine positive imaginäre Null. double imaginary z = 3*I; bool b = z; // Boolesche Konvertierung: setzt b auf true float f = z; // Real-Imaginär-Konvertierung: setzt f auf 0.0 z = 3.14; // Imaginär-Real-Konvertierung: setzt z auf 0*_Imaginary_I Komplex-Imaginär-KonvertierungenEin Wert jedes imaginären Typs kann implizit in jeden komplexen Typ konvertiert werden.
Ein Wert jedes komplexen Typs kann implizit in jeden imaginären Typ konvertiert werden.
double imaginary z = I * (3*I); // das komplexe Ergebnis -3.0+0i verliert den Realteil // setzt z auf 0*_Imaginary_I |
(seit C99) |
Zeigerkonvertierungen
Ein Zeiger auf void kann implizit zu und von jedem Zeiger auf einen Objekttyp mit der folgenden Semantik konvertiert werden:
- Wenn ein Zeiger auf ein Objekt in einen Zeiger auf void konvertiert und zurückkonvertiert wird, vergleicht sich sein Wert gleich mit dem ursprünglichen Zeiger.
- Es werden keine weiteren Garantien angeboten.
int* p = malloc(10 * sizeof(int)); // malloc gibt void* zurück
Ein Zeiger auf einen uneingeschränkten Typ kann implizit in den Zeiger auf die qualifizierte Version dieses Typs konvertiert werden (mit anderen Worten,
const
,
volatile
, und
restrict
Qualifizierer können hinzugefügt werden). Der ursprüngliche Zeiger und das Ergebnis vergleichen sich gleich.
int n; const int* p = &n; // &n hat den Typ int*
Jeder ganzzahlige konstante Ausdruck mit dem Wert 0 sowie jeder ganzzahlige Zeigerausdruck mit dem Wert Null, der in den Typ void * umgewandelt wird, kann implizit in jeden Zeigertyp konvertiert werden (sowohl Zeiger auf Objekt als auch Zeiger auf Funktion). Das Ergebnis ist der Nullzeigerwert seines Typs, der garantiert ungleich jedem Nicht-Null-Zeigerwert dieses Typs ist. Dieser ganzzahlige oder void * Ausdruck wird als Nullzeigerkonstante bezeichnet, und die Standardbibliothek stellt eine Definition dieser Konstante als Makro NULL bereit.
int* p = 0; double* q = NULL;
`-Tags wurde nicht übersetzt (wie angefordert) - C++-spezifische Begriffe wie `int`, `double`, `NULL` wurden nicht übersetzt - Die numerischen Werte `0` und Zeiger-Syntax `*` bleiben unverändert - Die Formatierung und Struktur des Originalcodes wurde vollständig erhalten
Hinweise
Obwohl ein Überlauf vorzeichenbehafteter Ganzzahlen in jedem arithmetischen Operator undefiniertes Verhalten ist, ist das Überlaufen eines vorzeichenbehafteten Ganzzahltyps in einer Ganzzahlkonvertierung lediglich nicht spezifiziertes Verhalten.
Andererseits ist das Überlaufen eines vorzeichenlosen Ganzzahlwerts in jedem arithmetischen Operator (und bei Ganzzahlkonvertierung) eine wohldefinierte Operation und folgt den Regeln der Modulo-Arithmetik, während das Überlaufen eines vorzeichenlosen Ganzzahlwerts bei einer Gleitkomma-zu-Ganzzahl-Konvertierung undefiniertes Verhalten darstellt: Die Werte des reellen Gleitkommatyps, die in vorzeichenlose Ganzzahlen konvertiert werden können, sind die Werte aus dem offenen Intervall
(
-1
,
Unnn_MAX
+ 1
)
.
unsigned int n = -1.0; // undefiniertes Verhalten
Umwandlungen zwischen Zeigern und Ganzzahlen (außer von Zeiger zu _Bool (bis C23) bool (seit C23) und (seit C99) von ganzzahligen konstanten Ausdrücken mit dem Wert null zu Zeigern), zwischen Zeigern auf Objekte (außer wenn einer der Zeiger ein Zeiger auf void ist) und Umwandlungen zwischen Zeigern auf Funktionen (außer wenn die Funktionen kompatible Typen haben) sind niemals implizit und erfordern einen Cast-Operator .
Es gibt keine Konvertierungen (weder implizit noch explizit) zwischen Zeigern auf Funktionen und Zeigern auf Objekte (einschließlich void * ) oder Ganzzahlen.
Referenzen
- C23-Standard (ISO/IEC 9899:2024):
-
- 6.3 Konvertierungen (S: 44-50)
- C17-Standard (ISO/IEC 9899:2018):
-
- 6.3 Konvertierungen (S: 37-41)
- C11-Standard (ISO/IEC 9899:2011):
-
- 6.3 Konvertierungen (S: 50-56)
- C99 Standard (ISO/IEC 9899:1999):
-
- 6.3 Konvertierungen (S: 42-48)
- C89/C90 Standard (ISO/IEC 9899:1990):
-
- 3.2 Konvertierungen
Siehe auch
|
C++ Dokumentation
für
Implizite Konvertierungen
|