cast operator
Führt explizite Typumwandlung durch
Inhaltsverzeichnis |
Syntax
(
Typname
)
Ausdruck
|
|||||||||
wo
| type-name | - | entweder der Typ void oder irgendein Skalartyp |
| expression | - | irgendein Ausdruck vom Skalartyp (außer wenn type-name void ist, in welchem Fall es beliebig sein kann) |
Erklärung
Wenn type-name void ist, dann wird expression für seine Nebeneffekte ausgewertet und sein Rückgabewert verworfen, genauso wie wenn expression allein verwendet wird, als eine Ausdrucksanweisung .
Andernfalls, falls type-name exakt dem Typ von expression entspricht, wird nichts unternommen (außer dass, falls expression einen Fließkommatyp hat und mit größerer Reichweite und Genauigkeit dargestellt wird als ihr Typ anzeigt – siehe unten).
Andernfalls wird der Wert des expression in den durch type-name benannten Typ konvertiert, wie folgt:
Jede implizite Konvertierung wie durch Zuweisung ist erlaubt.
Zusätzlich zu den impliziten Konvertierungen sind die folgenden Konvertierungen zulässig:
- Jede Ganzzahl kann in jeden Zeigertyp umgewandelt werden. Mit Ausnahme der Nullzeigerkonstanten wie NULL (die keine Umwandlung benötigt ), ist das Ergebnis implementierungsdefiniert, möglicherweise nicht korrekt ausgerichtet, zeigt möglicherweise nicht auf ein Objekt des referenzierten Typs und kann eine Trap-Darstellung sein.
- Jeder Zeigertyp kann in jeden Ganzzahltyp umgewandelt werden. Das Ergebnis ist implementierungsdefiniert, selbst für Nullzeigerwerte (sie führen nicht notwendigerweise zum Wert Null). Wenn das Ergebnis im Zieltyp nicht dargestellt werden kann, ist das Verhalten undefiniert (vorzeichenlose Ganzzahlen implementieren keine Modulo-Arithmetik bei einer Umwandlung von Zeigern).
- Jeder Objektzeiger kann in jeden anderen Objektzeiger umgewandelt werden. Wenn der Wert für den Zieltyp nicht korrekt ausgerichtet ist, ist das Verhalten undefiniert. Andernfalls, wenn der Wert zurück in den ursprünglichen Typ konvertiert wird, vergleicht er gleich mit dem ursprünglichen Wert. Wenn ein Objektzeiger in einen Zeiger auf einen Zeichentyp umgewandelt wird, zeigt das Ergebnis auf das niedrigste Byte des Objekts und kann bis zur Größe des Zieltyps erhöht werden (mit anderen Worten, kann verwendet werden, um die Objektdarstellung zu untersuchen oder eine Kopie mittels memcpy oder memmove zu erstellen).
- Jeder Funktionszeiger kann in einen Zeiger auf einen anderen Funktionstyp umgewandelt werden. Wenn der resultierende Zeiger zurück in den ursprünglichen Typ konvertiert wird, vergleicht er gleich mit dem ursprünglichen Wert. Wenn der konvertierte Zeiger verwendet wird, um einen Funktionsaufruf durchzuführen, ist das Verhalten undefiniert (es sei denn, die Funktionstypen sind kompatibel ).
- Bei Umwandlungen zwischen Zeigern (sowohl Objekt- als auch Funktionszeigern), wenn der ursprüngliche Wert ein Nullzeigerwert seines Typs ist, ist das Ergebnis der korrekte Nullzeigerwert für den Zieltyp.
In jedem Fall (sowohl bei der Ausführung einer impliziten Konvertierung als auch beim Cast desselben Typs), wenn expression und type-name Gleitkommatypen sind und expression mit größerer Reichweite und Präzision dargestellt wird als ihr Typ anzeigt (siehe FLT_EVAL_METHOD ), werden Reichweite und Präzision entfernt, um dem Zieltyp zu entsprechen.
Der Wertkategorie des Cast-Ausdrucks ist immer Non-Lvalue.
Hinweise
Da
const
,
volatile
,
restrict
und
_Atomic
Qualifizierer nur auf
Lvalues
wirken, ist eine Umwandlung in einen cvr-qualifizierten oder atomaren Typ genau gleichbedeutend mit der Umwandlung in den entsprechenden unqualifizierten Typ.
Die Umwandlung zu void ist manchmal nützlich, um Compiler-Warnungen über ungenutzte Ergebnisse zu unterdrücken.
Die hier nicht aufgeführten Konvertierungen sind nicht erlaubt. Insbesondere,
- Es gibt keine Konvertierungen zwischen Zeigern und Gleitkommatypen;
- Es gibt keine Konvertierungen zwischen Zeigern auf Funktionen und Zeigern auf Objekte (einschließlich void * ).
|
Falls die Implementierung intptr_t und/oder uintptr_t bereitstellt, dann ist eine Konvertierung von einem Zeiger auf einen Objekttyp (einschließlich cv void ) zu diesen Typen immer wohldefiniert. Dies ist jedoch für Funktionszeiger nicht garantiert. |
(seit C99) |
Beachten Sie, dass Konvertierungen zwischen Funktionszeigern und Objektzeigern als Erweiterungen von vielen Compilern akzeptiert werden und von einigen Verwendungen der POSIX
dlsym
-Funktion erwartet werden.
Beispiel
#include <stdio.h> int main(void) { // Die Untersuchung der Objektrepräsentation ist eine legitime Verwendung von Casts const double d = 3.14; printf("The double %.2f (%a) is: ", d, d); for (size_t n = 0; n != sizeof d; ++n) printf("%02X ", ((unsigned char*)&d)[n]); // Grenzfälle struct S { int x; } s; // (struct S)s; // Fehler; kein Skalartyp, obwohl // das Casten in denselben Typ nichts bewirkt (void)s; // Erlaubt, jeden Typ nach void zu casten }
Ausgabe:
The double 3.14 (0x1.91eb851eb851fp+1) is: 1F 85 EB 51 B8 1E 09 40
Referenzen
- C23-Standard (ISO/IEC 9899:2024):
-
- 6.5.5 Cast-Operatoren (S: 83-84)
- C17-Standard (ISO/IEC 9899:2018):
-
- 6.5.4 Cast-Operatoren (S: 65-66)
- C11-Standard (ISO/IEC 9899:2011):
-
- 6.5.4 Cast-Operatoren (S: 91)
- C99-Standard (ISO/IEC 9899:1999):
-
- 6.5.4 Cast-Operatoren (S: 81)
- C89/C90 Standard (ISO/IEC 9899:1990):
-
- 3.3.4 Cast-Operatoren
Siehe auch
|
C++ Dokumentation
für
explizite Typumwandlung
|