Implizite Konvertierungen
Wenn ein Ausdruck im Kontext verwendet wird, in dem ein Wert eines anderen Typs erwartet wird, kann eine Konvertierung stattfinden.
int n = 1L; // expression 1L has type long, int is expected n = 2.1; // expression 2.1 has type double, int is expected char *p = malloc(10); // expression malloc(10) has type void*, char* is expected
Konvertierungen finden in folgenden Situationen statt:
[bearbeiten] Konvertierung wie durch Zuweisung
- Im Zuweisungsoperator wird der Wert des rechten Operanden in den unqualifieden Typ des linken Operanden konvertiert.
- Bei der Skalarinitialisierung wird der Wert des Initialisierungsausdrucks in den unqualifieden Typ des zu initialisierenden Objekts konvertiert.
- In einem Funktionsaufrufausdruck wird der Wert jedes Argumentausdrucks in den Typ der unqualified deklarierten Typen des entsprechenden Parameters konvertiert, wenn der Aufruf an eine Funktion mit Prototyp erfolgt.
- In einer return-Anweisung wird der Wert des Operanden von
returnin ein Objekt mit dem Rückgabetyp der Funktion konvertiert.
Beachten Sie, dass die tatsächliche Zuweisung zusätzlich zur Konvertierung auch den zusätzlichen Bereich und die Präzision von Gleitkommatypen entfernt und Überlappungen verbietet; diese Eigenschaften gelten nicht für die Konvertierung wie durch Zuweisung.
[bearbeiten] Standard-Argument-Promotions
Bei einem Funktionsaufrufausdruck, wenn der Aufruf erfolgt an
Jedes Argument vom Integer-Typ unterliegt einer Integer-Promotion (siehe unten), und jedes Argument vom Typ float wird implizit in den Typ double konvertiert.
int add_nums(int count, ...); int sum = add_nums(2, 'c', true); // add_nums is called with three ints: (2, 99, 1)
|
Beachten Sie, dass float complex und float imaginary in diesem Kontext nicht zu double complex und double imaginary promoted werden. |
(seit C99) |
[bearbeiten] Übliche arithmetische Konvertierungen
Die Operanden der folgenden arithmetischen Operatoren unterliegen impliziten Konvertierungen zur Ermittlung des gemeinsamen Realtyps, in dem die Berechnung durchgeführt wird:
- binäre arithmetische Operatoren *, /, %, +, -
- relationale Operatoren <, >, <=, >=, ==, !=
- binäre bitweise arithmetische Operatoren &, ^, |,
- der bedingte Operator ?:
|
1) Wenn ein Operand vom Typ "decimal floating type" ist, darf der andere Operand nicht von einem Standard-Floating-, komplexen oder imaginären Typ sein.
komplexen oder imaginären Typ sein.
|
(seit C23) |
- Integer- oder Real-Floating-Typ zu long double
| (seit C99) |
- Integer- oder Real-Floating-Typ zu double
| (seit C99) |
- Integer-Typ zu float (der einzige mögliche Realtyp ist float, der unverändert bleibt)
| (seit C99) |
- Wenn die Typen gleich sind, ist dieser Typ der gemeinsame Typ.
- Wenn die Typen unterschiedlich sind.
- Wenn die Typen die gleiche Vorzeichenigkeit haben (beide vorzeichenbehaftet oder beide vorzeichenlos), wird der Operand, dessen Typ den geringeren Konvertierungsrang1 hat, implizit2 in den anderen Typ konvertiert.
- Wenn andernfalls die Operanden unterschiedliche Vorzeichenigkeit haben.
- Wenn der vorzeichenlose Typ einen Konvertierungsrang hat, der größer oder gleich dem Rang des vorzeichenbehafteten Typs ist, dann wird der Operand mit dem vorzeichenbehafteten Typ in den vorzeichenlosen Typ implizit konvertiert.
- Wenn andernfalls der vorzeichenlose Typ einen geringeren Konvertierungsrang als der vorzeichenbehaftete Typ hat.
- 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.
- Wenn andernfalls beide Operanden einer impliziten Konvertierung in den vorzeichenlosen Gegenstücktyp des vorzeichenbehafteten Operanden unterliegen.
- 1. Informationen zu den Regeln für die Rangordnung finden Sie unter "Integer-Promotions" unten.
- 2. Informationen zu den "Integer-Konvertierungen" unter "Semantik impliziter Konvertierungen" finden Sie unten.
1.f + 20000001; // int is converted to float, giving 20000000.00 // addition and then rounding to float gives 20000000.00 (char)'a' + 1L; // first, char 'a', which is 97, is promoted to int // different types: int and long // same signedness: both signed // different rank: long is of greater rank than int // therefore, int 97 is converted to long 97 // the result is 97 + 1 = 98 of type signed long 2u - 10; // different types: unsigned int and signed int // different signedness // same rank // therefore, signed int 10 is converted to unsigned int 10 // since the arithmetic operation is performed for unsigned integers // (see "Arithmetic operators" topic), the calculation performed is (2 - 10) // modulo (2 raised to n), where n is the number of value bits of unsigned int // if unsigned int is 32-bit long and there is no padding bits in its object // representation, then the result is (-8) modulo (2 raised to 32) = 4294967288 // of type unsigned int 5UL - 2ULL; // different types: unsigned long and unsigned long long // same signedness // different rank: rank of unsigned long long is greater // therefore, unsigned long 5 is converted to unsigned long long 5 // since the arithmetic operation is performed for unsigned integers // (see "Arithmetic operators" topic), // if unsigned long long is 64-bit long, then // the result is (5 - 2) modulo (2 raised to 64) = 3 of type // unsigned long long 0UL - 1LL; // different types: unsigned long and signed long long // different signedness // different rank: rank of signed long long is greater. // if ULONG_MAX > LLONG_MAX, then signed long long cannot represent all // unsigned long therefore, this is the last case: both operands are converted // to unsigned long long unsigned long 0 is converted to unsigned long long 0 // long long 1 is converted to unsigned long long 1 since the arithmetic // operation is performed for unsigned integers // (see "Arithmetic operators" topic), // if unsigned long long is 64-bit long, then // the calculation is (0 - 1) modulo (2 raised to 64) // thus, the result is 18446744073709551615 (ULLONG_MAX) of type // 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 Gleitkommaoperators einen größeren Bereich und eine höhere Präzision aufweisen, als durch seinen Typ angezeigt wird (siehe FLT_EVAL_METHOD).
|
Hinweis: Reelle und imaginäre Operanden werden nicht implizit in komplexe konvertiert, da dies zusätzliche Berechnungen erfordern und in bestimmten Fällen mit Unendlichkeiten, NaNs und vorzeichenbehafteten Nullen unerwünschte Ergebnisse liefern würde. Zum Beispiel würde 2.0×(3.0+i∞) als (2.0+i0.0)×(3.0+i∞) ⇒ (2.0×3.0–0.0×∞) + i(2.0×∞+0.0×3.0) ⇒ NaN+i∞ ausgewertet, anstatt des korrekten 6.0+i∞. Wenn Imaginäre 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∞ statt –6.0 + i∞ ausgewertet. |
(seit C99) |
Hinweis: Unabhängig von den üblichen arithmetischen Konvertierungen kann die Berechnung gemäß der "as-if"-Regel stets in einem schmaleren Typ als den nach diesen Regeln angegebenen durchgeführt werden.
[bearbeiten] Werttransformationen
[bearbeiten] Lvalue-Konvertierung
Jeder lvalue-Ausdruck eines beliebigen Nicht-Array-Typs, wenn er in einem anderen Kontext als
- als Operand des Adressoperator (falls zulässig)
- als Operand der Prä-/Post-Inkrement- und Dekrementoperatoren.
- als linker Operand des Member-Access-Operators (Punkt).
- als linker Operand der Zuweisungs- und zusammengesetzten Zuweisungsoperatoren.
- als Operand von sizeof
verwendet wird, unterliegt einer lvalue-Konvertierung: Der Typ bleibt gleich, verliert jedoch Const-/Volatile-/Restrict-Qualifizierer und atomare Eigenschaften, falls vorhanden. Der Wert bleibt gleich, verliert jedoch seine lvalue-Eigenschaften (die Adresse darf nicht mehr genommen werden).
Wenn das lvalue einen unvollständigen Typ hat, ist das Verhalten undefiniert.
Wenn das lvalue ein Objekt mit automatischer Speicherdauer bezeichnet, dessen Adresse nie genommen wurde und wenn dieses Objekt uninitialisiert war (nicht mit einem Initialisierer deklariert und vor der Verwendung keine Zuweisung dazu erfolgt ist), ist das Verhalten undefiniert.
Diese Konvertierung modelliert das Laden des Wertes des Objekts aus seinem Speicherort.
volatile int n = 1; int x = n; // lvalue conversion on n reads the value of n volatile int* p = &n; // no lvalue conversion: does not read the value of n
[bearbeiten] Array-zu-Zeiger-Konvertierung
Jeder lvalue-Ausdruck vom Array-Typ, wenn er in einem anderen Kontext als
- als Operand des Adressoperator
- als Operand von sizeof
- als Operand von typeof und typeof_unqual (seit C23)
- als String-Literal für die Array-Initialisierung
verwendet wird, unterliegt einer Konvertierung in den Nicht-lvalue-Zeiger auf sein erstes Element.
Wenn das Array als register deklariert war, ist das Verhalten undefiniert.
int a[3], b[3][4]; int* p = a; // conversion to &a[0] int (*q)[4] = b; // conversion to &b[0]
[bearbeiten] Funktion-zu-Zeiger-Konvertierung
Jeder Funktionsdeskriptor-Ausdruck, wenn er in einem anderen Kontext als
- als Operand des Adressoperator
- als Operand von sizeof
- als Operand von typeof und typeof_unqual (seit C23)
verwendet wird, unterliegt einer Konvertierung in den Nicht-lvalue-Zeiger auf die durch den Ausdruck bezeichnete Funktion.
int f(int); int (*p)(int) = f; // conversion to &f (***p)(1); // repeated dereference to f and conversion back to &f
[bearbeiten] Semantik impliziter Konvertierungen
Die implizite Konvertierung, ob wie durch Zuweisung oder übliche arithmetische Konvertierung, besteht aus zwei Stufen:
[bearbeiten] Kompatible Typen
Die Konvertierung eines Wertes eines beliebigen Typs in einen beliebigen kompatiblen Typ ist immer eine No-Op und ändert die Darstellung nicht.
uint8_t (*a)[10]; // if uint8_t is a typedef to unsigned char unsigned char (*b)[] = a; // then these pointer types are compatible
[bearbeiten] Integer-Promotions
Die Integer-Promotion ist die implizite Konvertierung eines Wertes eines beliebigen Integer-Typs mit einem Rang kleiner oder gleich dem Rang von int oder eines Bitfeldes 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 Bitfeldes) darstellen kann, wird der Wert in den Typ int konvertiert. Andernfalls wird der Wert in unsigned int konvertiert.
|
Der Wert eines Bitfeldes eines bitpräzisen Integer-Typs wird in den entsprechenden bitpräzisen Integer-Typ konvertiert. Andernfalls sind bitpräzise Integer-Typen von den Regeln für Integer-Promotions ausgenommen. |
(seit C23) |
Integer-Promotions erhalten den Wert, einschließlich des Vorzeichens.
int main(void) { void f(); // old-style function declaration // since C23, void f(...) has the same behavior wrt promotions char x = 'a'; // integer conversion from int to char f(x); // integer promotion from char back to int } void f(x) int x; {} // the function expects int
Rang oben ist eine Eigenschaft jedes Integer-Typs und ist wie folgt definiert:
|
8) Der Rang eines vorzeichenbehafteten bitpräzisen Integer-Typs muss größer sein als der Rang eines Standard-Integer-Typs mit geringerer Breite oder eines bitpräzisen Integer-Typs mit geringerer Breite.
9) Der Rang eines beliebigen bitpräzisen Integer-Typs im Verhältnis zu einem erweiterten Integer-Typ gleicher Breite ist implementierungsabhängig.
|
(seit C23) |
Hinweis: Integer-Promotions werden nur angewendet
- als Teil von üblichen arithmetischen Konvertierungen (siehe oben)
- als Teil von Standard-Argument-Promotions (siehe oben)
- auf den Operanden der unären arithmetischen Operatoren + und -
- auf den Operanden des unären bitweisen Operators ~
- auf beide Operanden der Verschiebungsoperatoren << und >>
Boolesche KonvertierungEin Wert eines beliebigen Skalar-Typs kann implizit in _Bool(bis C23)bool(seit C23) konvertiert werden. Werte, die mit einem ganzzahligen konstanten Ausdruck mit dem Wert null übereinstimmen(bis C23)null (für arithmetische Typen), null (für Zeigertypen) oder einen Typ nullptr_t haben(seit C23) sind, werden zu 0(bis C23)false(seit C23) konvertiert, alle anderen Werte werden zu 1(bis C23)true(seit C23) konvertiert. 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) |
[bearbeiten] Integer-Konvertierungen
Ein Wert eines beliebigen Integer-Typs kann implizit in jeden anderen Integer-Typ konvertiert werden. Außer wo oben durch Promotions und boolesche Konvertierungen abgedeckt, gelten die Regeln:
- Wenn der Zieltyp den Wert darstellen kann, bleibt der Wert unverändert.
- Wenn der Zieltyp vorzeichenlos ist, wird 2b
, wobei b die Anzahl der Wertbits im Zieltyp ist, wiederholt vom Quellwert subtrahiert oder hinzugefügt, bis das Ergebnis in den Zieltyp passt. Mit anderen Worten, vorzeichenlose Integer implementieren Modulo-Arithmetik. - Wenn der Zieltyp vorzeichenbehaftet ist, ist das Verhalten implementierungsabhängig (was die Auslösung eines Signals einschließen kann).
char x = 'a'; // int -> char, result unchanged unsigned char n = -123456; // target is unsigned, result is 192 (that is, -123456+483*256) signed char m = 123456; // target is signed, result is implementation-defined assert(sizeof(int) > -1); // assert fails: // operator > requests conversion of -1 to size_t, // target is unsigned, result is SIZE_MAX
[bearbeiten] Real-Floating-Integer-Konvertierungen
Ein endlicher Wert eines beliebigen reellen Gleitkommatyps kann implizit in jeden Integer-Typ konvertiert werden. Außer wo oben durch boolesche Konvertierung abgedeckt, gelten die Regeln:
- Der Nachkommateil wird verworfen (gegen Null abgeschnitten).
- Wenn der resultierende Wert vom Zieltyp dargestellt werden kann, wird dieser Wert verwendet.
- Andernfalls ist das Verhalten undefiniert.
int n = 3.14; // n == 3 int x = 1e10; // undefined behavior for 32-bit int
Ein Wert eines beliebigen Integer-Typs kann implizit in jeden reellen Gleitkommatyp konvertiert werden.
- Wenn der Wert exakt vom Zieltyp dargestellt werden kann, bleibt er unverändert.
- Wenn der Wert dargestellt werden kann, aber nicht exakt, ist das Ergebnis eine implementierungsabhängige Wahl zwischen dem nächsthöheren oder nächstniedrigeren Wert (obwohl bei Unterstützung von IEEE-Arithmetik die Rundung zum Nächsten erfolgt). 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 Unterstützung von IEEE-Arithmetik FE_INVALID ausgelöst wird und der Ergebniswert nicht spezifiziert ist.
Das Ergebnis dieser Konvertierung kann einen größeren Bereich und eine höhere Präzision aufweisen, als sein Zieltyp angibt (siehe FLT_EVAL_METHOD).
Wenn Steuerung über FE_INEXACT bei Gleitkomma-zu-Integer-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; // undefined behavior
[bearbeiten] Real-Floating-Point-Konvertierungen
Ein Wert eines beliebigen reellen Gleitkommatyps kann implizit in jeden anderen reellen Gleitkommatyp konvertiert werden.
- Wenn der Wert exakt vom 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 (d. h. die Rundungsrichtung ist implementierungsabhängig), obwohl bei Unterstützung von IEEE-Arithmetik die Rundung zum Nächsten erfolgt.
- Wenn der Wert nicht dargestellt werden kann, ist das Verhalten undefiniert.
Dieser Abschnitt ist unvollständig
Grund: Überprüfung von IEEE, wenn ein entsprechend vorzeichenbehaftete Unendlichkeit erforderlich ist.
Das Ergebnis dieser Konvertierung kann einen größeren Bereich und eine höhere Präzision aufweisen, als sein 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; // undefined
Komplexe TypkonvertierungenEin Wert eines beliebigen komplexen Typs kann implizit in jeden anderen komplexen Typ konvertiert werden. Der Realteil und der Imaginärteil folgen einzeln den Konvertierungsregeln für reelle Gleitkommatypen. Imaginäre TypkonvertierungenEin Wert eines beliebigen imaginären Typs kann implizit in jeden anderen imaginären Typ konvertiert werden. Der Imaginärteil folgt den Konvertierungsregeln für reelle Gleitkommatypen. double imaginary d = 0.1*_Imaginary_I; float imaginary f = d; // f is 0.100000001490116119384765625*I Real-Komplexe KonvertierungenEin Wert eines beliebigen reellen Gleitkommatyps kann implizit in jeden komplexen Typ konvertiert werden.
Ein Wert eines beliebigen komplexen Typs kann implizit in jeden reellen Gleitkommatyp konvertiert werden.
Hinweis: Bei komplex-zu-reeller Konvertierung wird ein NaN im Imaginärteil nicht auf das reelle Ergebnis übertragen. double complex z = 0.5 + 3*I; float f = z; // the imaginary part is discarded, f is set to 0.5 z = f; // sets z to 0.5 + 0*I Real-Imaginäre KonvertierungenEin Wert eines beliebigen imaginären Typs kann implizit in jeden reellen Typ (Integer oder Gleitkomma) 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 Regeln für boolesche Konvertierungen gelten. Ein Wert eines beliebigen 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; // Boolean conversion: sets b to true float f = z; // Real-imaginary conversion: sets f to 0.0 z = 3.14; // Imaginary-real conversion: sets z to 0*_Imaginary_I Komplex-Imaginäre KonvertierungenEin Wert eines beliebigen imaginären Typs kann implizit in jeden komplexen Typ konvertiert werden.
Ein Wert eines beliebigen komplexen Typs kann implizit in jeden imaginären Typ konvertiert werden.
double imaginary z = I * (3*I); // the complex result -3.0+0i loses real part // sets z to 0*_Imaginary_I |
(seit C99) |
[bearbeiten] Zeigerkonvertierungen
Ein Zeiger auf void kann implizit in jeden Zeiger auf einen Objekttyp konvertiert und von diesem zurückkonvertiert werden, mit den folgenden Semantiken:
- Wenn ein Zeiger auf ein Objekt in einen Zeiger auf void konvertiert und zurückkonvertiert wird, vergleicht sein Wert gleich dem ursprünglichen Zeiger.
- Es werden keine weiteren Garantien gegeben.
int* p = malloc(10 * sizeof(int)); // malloc returns void*
Ein Zeiger auf einen nicht qualifizierten Typ darf implizit in die qualifizierte Version dieses Typs konvertiert werden (mit anderen Worten, const, volatile und restrict Qualifikatoren können hinzugefügt werden). Der ursprüngliche Zeiger und das Ergebnis vergleichen sich gleich.
int n; const int* p = &n; // &n has type int*
Jeder ganzzahlige Konstanten Ausdruck mit dem Wert 0 sowie ein ganzzahliger Zeigerausdruck mit dem Wert Null, der in den Typ void* umgewandelt wird, kann implizit in jeden Zeigertyp (sowohl Zeiger auf Objekt als auch Zeiger auf Funktion) konvertiert werden. Das Ergebnis ist der Nullzeigerwert seines Typs, der garantiert ungleich jedem Nicht-Null-Zeigerwert dieses Typs ist. Dieser ganzzahlige oder void* Ausdruck wird als Nullzeiger-Konstante bezeichnet und die Standardbibliothek stellt eine Definition dieser Konstante als Makro NULL bereit.
int* p = 0; double* q = NULL;
[bearbeiten] Hinweise
Obwohl ein Überlauf vorzeichenbehafteter Ganzzahlen bei jedem arithmetischen Operator undefiniertes Verhalten darstellt, ist der Überlauf eines vorzeichenbehafteten Ganzzahltyps bei einer Ganzzahlkonvertierung lediglich nicht spezifiziertes Verhalten.
Andererseits, obwohl ein Überlauf vorzeichenloser Ganzzahlen bei jedem arithmetischen Operator (und bei Ganzzahlkonvertierungen) eine wohldefinierte Operation ist und den Regeln der Modulo-Arithmetik folgt, ist ein Überlauf vorzeichenloser Ganzzahlen bei einer Konvertierung von Gleitkommazahlen zu Ganzzahlen undefiniertes Verhalten: Die Werte vom Typ Real-Gleitkommazahl, die in vorzeichenlose Ganzzahlen konvertiert werden können, sind die Werte aus dem offenen Intervall (-1; Unnn_MAX+1).
unsigned int n = -1.0; // undefined behavior
Konvertierungen zwischen Zeigern und Ganzzahlen (außer von Zeiger auf _Bool(bis C23)bool(seit C23) und (seit C99) von ganzzahligen Konstanten Ausdrücken mit dem Wert Null zu Zeiger), zwischen Zeigern auf Objekte (außer wenn einer oder beide Zeiger auf void sind) und Konvertierungen zwischen Zeigern auf Funktionen (außer wenn die Funktionen kompatible Typen haben) sind niemals implizit und erfordern einen Cast-Operator.
Es gibt keine Konvertierungen (implizit oder explizit) zwischen Zeigern auf Funktionen und Zeigern auf Objekte (einschließlich void*) oder Ganzzahlen.
[bearbeiten] Referenzen
- C23-Standard (ISO/IEC 9899:2024)
- 6.3 Konvertierungen (S. TBD)
- 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
[bearbeiten] Siehe auch
| C++ Dokumentation für Implizite Konvertierungen
|