Namensräume
Varianten
Aktionen

cast operator

Von cppreference.com
< c‎ | Sprache

Führt explizite Typumwandlungen durch

Inhalt

[bearbeiten] Syntax

( type-name ) expression

wobei

Typname - entweder der Typ void oder ein beliebiger skalarer Typ
expression - beliebige Ausdrücke von skalarem Typ (es sei denn, type-name ist void, in welchem Fall es alles sein kann)

[bearbeiten] Erläuterung

Wenn type-name void ist, wird expression auf seine Seiteneffekte hin ausgewertet und sein Rückgabewert verworfen, genau wie wenn expression allein als Ausdrucksanweisung verwendet wird.

Andernfalls, wenn type-name genau dem Typ von expression entspricht, wird nichts getan (außer dass, wenn expression vom Fließkommatyp ist und mit größerer Reichweite und Präzision dargestellt wird, als sein Typ angibt - siehe unten).

Andernfalls wird der Wert von expression in den durch type-name bezeichneten Typ konvertiert, wie folgt:

Jede implizite Konvertierung wie bei einer Zuweisung ist zulässig.

Zusätzlich zu den impliziten Konvertierungen sind folgende Konvertierungen zulässig:

  • Jede Ganzzahl kann in jeden Zeigertyp konvertiert werden. Außer für Nullzeigerkonstanten wie NULL (die keine Konvertierung erfordern) ist das Ergebnis implementierungsdefiniert, möglicherweise nicht korrekt ausgerichtet, zeigt möglicherweise nicht auf ein Objekt des referenzierten Typs und kann eine Trap-Repräsentation sein.
  • Jeder Zeigertyp kann in jeden Ganzzahltyp konvertiert werden. Das Ergebnis ist implementierungsdefiniert, selbst für Nullzeigerwerte (sie ergeben nicht notwendigerweise den Wert Null). Wenn das Ergebnis nicht im Zieltyp dargestellt werden kann, ist das Verhalten undefiniert (Ganzzahlen ohne Vorzeichen implementieren bei einer Konvertierung von einem Zeiger keine Modulo-Arithmetik).
  • Jeder Zeiger auf ein Objekt kann in jeden anderen Zeiger auf ein Objekt konvertiert 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, ist er mit dem ursprünglichen Wert gleich. Wenn ein Zeiger auf ein Objekt in einen Zeiger auf einen beliebigen Zeigertyp konvertiert wird, zeigt das Ergebnis auf das niedrigste Byte des Objekts und kann bis zu sizeof des Zieltyps inkrementiert werden (mit anderen Worten, es kann zur Untersuchung der Objektdarstellung oder zum Erstellen einer Kopie mittels memcpy oder memmove verwendet werden).
  • Jeder Zeiger auf eine Funktion kann in einen Zeiger auf jeden anderen Funktionstyp konvertiert werden. Wenn der resultierende Zeiger zurück in den ursprünglichen Typ konvertiert wird, ist er mit dem ursprünglichen Wert gleich. Wenn der konvertierte Zeiger verwendet wird, um einen Funktionsaufruf zu tätigen, ist das Verhalten undefiniert (es sei denn, die Funktionstypen sind kompatibel).
  • Bei der Konvertierung zwischen Zeigern (sowohl Objekt- als auch Funktionszeiger) ist das Ergebnis, wenn der ursprüngliche Wert ein Nullzeigerwert seines Typs ist, der korrekte Nullzeigerwert für den Zieltyp.

In jedem Fall (sowohl bei der Ausführung einer impliziten Konvertierung als auch bei der Gleichheitstyp-Konvertierung) werden, wenn expression und type-name Fließkommatypen sind und expression mit größerer Reichweite und Präzision dargestellt wird, als sein Typ angibt (siehe FLT_EVAL_METHOD), Reichweite und Präzision gestrippt, um dem Zieltyp zu entsprechen.

Die Wertkategorie des Cast-Ausdrucks ist immer nicht-L-Wert.

[bearbeiten] Hinweise

Da const, volatile, restrict und _Atomic Qualifizierer nur Auswirkungen auf L-Werte haben, ist eine Konvertierung zu einem cvr-qualifizierten oder atomaren Typ exakt äquivalent zu der Konvertierung zum entsprechenden nicht-qualifizierten Typ.

Die Konvertierung zu void ist manchmal nützlich, um Compiler-Warnungen über ungenutzte Ergebnisse zu unterdrücken.

Die hier nicht aufgeführten Konvertierungen sind nicht zulässig. Insbesondere:

  • es gibt keine Konvertierungen zwischen Zeigern und Fließkommatypen
  • es gibt keine Konvertierungen zwischen Funktionszeigern und Zeigern auf Objekte (einschließlich void*)

Wenn die Implementierung intptr_t und/oder uintptr_t bereitstellt, ist eine Konvertierung von einem Zeiger auf einen Objekttyp (einschließlich cv void) in diese Typen immer wohl-definiert. Dies ist jedoch nicht für einen Funktionszeiger garantiert.

(seit C99)

Beachten Sie, dass Konvertierungen zwischen Funktions- und Objektzeigern von vielen Compilern als Erweiterungen akzeptiert werden und von einigen Verwendungen der POSIX dlsym() Funktion (POSIX dlsym() Funktion) erwartet werden.

[bearbeiten] Beispiel

#include <stdio.h>
 
int main(void)
{
    // examining object representation is a legitimate use of cast
    double d = 3.14;
    printf("The double %.2f (%a) is: ", d, d);
    for (size_t n = 0; n < sizeof d; ++n)
        printf("0x%02x ", ((unsigned char*)&d)[n]);
 
    // edge cases
    struct S { int x; } s;
//    (struct S)s; // error; not a scalar type
                   // even though casting to the same type does nothing
    (void)s; // okay to cast any type to void
}

Mögliche Ausgabe

The double 3.14 (0x1.91eb851eb851fp+1) is: 0x1f 0x85 0xeb 0x51 0xb8 0x1e 0x09 0x40

[bearbeiten] Referenzen

  • C23-Standard (ISO/IEC 9899:2024)
  • 6.5.4 Cast operators (p: TBD)
  • C17-Standard (ISO/IEC 9899:2018)
  • 6.5.4 Cast operators (p: 65-66)
  • C11-Standard (ISO/IEC 9899:2011)
  • 6.5.4 Cast operators (p: 91)
  • C99-Standard (ISO/IEC 9899:1999)
  • 6.5.4 Cast operators (p: 81)
  • C89/C90-Standard (ISO/IEC 9899:1990)
  • 3.3.4 Cast operators

[bearbeiten] Siehe auch

C++ Dokumentation für explizite Typumwandlung