Namespaces
Variants

cast operator

From cppreference.net

Effectue une conversion de type explicite

Table des matières

Syntaxe

( nom-type ) expression

type-name - soit le type void ou tout type scalaire
expression - toute expression de type scalaire (sauf si type-name est void , auquel cas cela peut être n'importe quoi)

Explication

Si type-name est void , alors expression est évaluée pour ses effets de bord et sa valeur de retour est ignorée, de la même manière que lorsque expression est utilisée seule, comme une instruction d'expression .

Sinon, si type-name correspond exactement au type de expression , aucune action n'est effectuée (sauf si expression est de type flottant et est représentée avec une plage et une précision supérieures à ce qu'indique son type – voir ci-dessous).

Sinon, la valeur de expression est convertie vers le type désigné par type-name , comme suit :

Toute conversion implicite comme par affectation est autorisée.

En plus des conversions implicites, les conversions suivantes sont autorisées :

  • Tout entier peut être converti en n'importe quel type pointeur. À l'exception des constantes de pointeur nul telles que NULL (qui ne nécessite pas de conversion ), le résultat est défini par l'implémentation, peut ne pas être correctement aligné, peut ne pas pointer vers un objet du type référencé, et peut être une représentation piégée .
  • N'importe quel type pointeur peut être converti en n'importe quel type entier. Le résultat est défini par l'implémentation, même pour les valeurs de pointeur nul (elles ne donnent pas nécessairement la valeur zéro). Si le résultat ne peut pas être représenté dans le type cible, le comportement est indéfini (les entiers non signés n'implémentent pas l'arithmétique modulo lors d'une conversion depuis un pointeur).
  • N'importe quel pointeur vers objet peut être converti en n'importe quel autre pointeur vers objet. Si la valeur n'est pas correctement alignée pour le type cible, le comportement est indéfini. Sinon, si la valeur est reconvertie vers le type original, elle est égale à la valeur originale. Si un pointeur vers objet est converti en pointeur vers n'importe quel type caractère, le résultat pointe vers l'octet le plus bas de l'objet et peut être incrémenté jusqu'à la taille du type cible (en d'autres termes, peut être utilisé pour examiner la représentation d'objet ou pour effectuer une copie via memcpy ou memmove ).
  • N'importe quel pointeur vers fonction peut être converti en pointeur vers n'importe quel autre type de fonction. Si le pointeur résultant est reconverti vers le type original, il est égal au pointeur original. Si le pointeur converti est utilisé pour effectuer un appel de fonction, le comportement est indéfini (sauf si les types de fonction sont compatibles ).
  • Lors d'une conversion entre pointeurs (qu'il s'agisse d'objets ou de fonctions), si la valeur originale est une valeur de pointeur nul de son type, le résultat est la valeur correcte de pointeur nul pour le type cible.

Dans tous les cas (à la fois lors de l'exécution d'une conversion implicite et dans le cast de même type), si expression et type-name sont des types flottants et que expression est représentée avec une plage et une précision supérieures à ce qu'indique son type (voir FLT_EVAL_METHOD ), la plage et la précision sont réduites pour correspondre au type cible.

La catégorie de valeur de l'expression de cast est toujours non-lvalue.

Notes

Parce que const , volatile , restrict , et _Atomic qualificateurs n'ont d'effet que sur les lvalues , un cast vers un type qualifié cvr ou atomique est exactement équivalent au cast vers le type non qualifié correspondant.

La conversion en void est parfois utile pour supprimer les avertissements du compilateur concernant les résultats non utilisés.

Les conversions non listées ici ne sont pas autorisées. En particulier,

  • il n'y a pas de conversions entre les pointeurs et les types flottants ;
  • il n'y a pas de conversions entre les pointeurs vers des fonctions et les pointeurs vers des objets (incluant void * ).

Si l'implémentation fournit intptr_t et/ou uintptr_t , alors une conversion d'un pointeur vers un type d'objet (incluant cv void ) vers ces types est toujours bien définie. Cependant, cela n'est pas garanti pour un pointeur de fonction.

(depuis C99)

Notez que les conversions entre pointeurs de fonction et pointeurs d'objet sont acceptées comme extensions par de nombreux compilateurs, et attendues par certaines utilisations de la fonction POSIX dlsym .

Exemple

#include <stdio.h>
int main(void)
{
    // examining object representation is a legitimate use of cast
    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]);
    // 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
}

Sortie :

The double 3.14 (0x1.91eb851eb851fp+1) is: 1F 85 EB 51 B8 1E 09 40

Références

  • Norme C23 (ISO/IEC 9899:2024):
  • 6.5.5 Opérateurs de cast (p: 83-84)
  • Norme C17 (ISO/IEC 9899:2018):
  • 6.5.4 Opérateurs de cast (p: 65-66)
  • Norme C11 (ISO/CEI 9899:2011) :
  • 6.5.4 Opérateurs de cast (p: 91)
  • Norme C99 (ISO/IEC 9899:1999) :
  • 6.5.4 Opérateurs de cast (p: 81)
  • Norme C89/C90 (ISO/IEC 9899:1990) :
  • 3.3.4 Opérateurs de cast

Voir aussi

Documentation C++ pour conversion de type explicite