Quel est exactement un type cast en C/C++?
Ce qui est exactement un type cast en C/C++? Comment le compilateur de vérifier si un transtypage explicite est nécessaire (et valide)? Est-il comparer l'espace requis pour une valeur? Si j'ai par exemple:
int a;
double b = 15.0;
a = (int) b;
Si je me souviens bien un double de la valeur nécessite plus d'espace (il était de 8 octets?!) qu'un entier (4 octets). Et la représentation interne de tous les deux sont complètement différents (complément à deux/mantisse). Donc ce qui se passe à l'interne? L'exemple ici est assez simple, mais en C/C++ nombreux sont les typecasts.
Comment le compilateur de savoir (ou programmeur) si je lance par exemple FOO BAR?
- Toute explication de type diffuse doit inclure standard conversions conversions définies par l'utilisateur,
reinterpret_cast
,const_cast
, upcasts, downcasts, de la croix-plâtres, RTTI, et les types de valeur. (Et je crois que j'ai oublié un sujet). - double possible de Quand doit-static_cast, dynamic_cast et reinterpret_cast être utilisé?
- Je crois que j'ai mentionné la grande majorité d'entre eux, à mon humble réponse, mais pas de (relativement concis) réponse peut éventuellement être considérée comme complète.
- Votre <strike>répondre</strike> modifier n'avait pas encore manifesté quand j'ai écrit que, il y avait juste deux réponses très brèves, qui portait sur des double->int conversions.
- oui, il a fallu un certain temps pour améliorer ma réponse avec plus de détails peut-être que ce qui était demandé. Mais, j'en suis venu à la même réalisation que vous et a décidé que le niveau de détail est nécessaire d'essayer de venir avec un peu de réponse complète à la question générale.
Vous devez vous connecter pour publier un commentaire.
Un type de distribution est essentiellement une conversion d'un type à l'autre. Il peut être implicite (c'est à dire, fait automatiquement par le compilateur, peut-être perdre de l'info dans le processus) ou explicite (c'est à dire, spécifié par le développeur dans le code). L'espace occupé par les types est d'une importance secondaire. Le plus important est le champ d'application (et parfois convenice) de la conversion.
Il est possible pour les conversions implicites de perdre de l'information, la signalisation peut être perdu /gagné, de dépassement et /underflow peut se produire. Le compilateur ne sera pas vous protéger de ces événements, à l'exception peut-être par un avertissement est généré au moment de la compilation. Découpage peut également se produire lorsqu'un type dérivé est implicitement converti en un type de base (en valeur).
Pour les conversions qui peuvent être carrément dangereux (par exemple, à partir d'une base d'un type dérivé), la norme C++ nécessite un cast explicite. Non seulement cela, mais il offre plus restrictive des conversions explicites, comme
static_cast
,dynamic_cast
,reinterpret_cast
, etconst_cast
, chaque de ce qui restreint encore le cast explicite qu'un sous-ensemble de conversions possibles, réduisant ainsi le potentiel pour des erreurs de conversion.Valide conversions implicites et explicit sont en fin de compte définie par le C/C++ normes, bien qu'en C++, le développeur a la possibilité d'étendre les conversions de types définis par l'utilisateur, à la fois implicite et explicite, via l'utilisation des constructeurs et de surcharge (cast) les opérateurs.
Les règles complètes pour laquelle les castes sont permises par les normes et qui ne sont pas peut-être assez complexe. J'ai essayé de présenter fidèlement un peu bref résumé de certaines de ces règles dans cette réponse. Si vous êtes vraiment intéressé dans ce qui est et n'est pas autorisé, je vous invite fortement à visiter, les normes et lire les sections respectives sur la conversion de type.
static_cast
. Vous n'avez pas besoin de la verbosité de ces différenciées jette ici.Veux juste mentionner quelque chose de souvent négligé:
Cela peut être important. Par exemple:
Que le cast SEMBLE inutile. Mais les apparences sont parfois trompeuses.
void change_one_print_other( int& a, const int& b ); change_one_print_other(y, static_cast<int>(y));
Si vous souhaitez éviter cette erreur (passage d'une référence à un temporaire), vous avez besoin de prendre un pointeur:void change_one_print_other( int& a, const int* pb );
À tout le monde ici: je suis nouveau sur ce système, désolé si je n'utilise pas les fonctionnalités du site correctement.p
est temporaire. Vous pouvez penser à une référence de la même manière, mais depuis nommer une référence donne toujours la valeur qu'elle renvoie à (la référence est totalement transparent), il est impossible de dire si un renvoi temporaire a été créé. Tout comme vous ne pouvez pas demander au compilateur comment grand une référence est, vous ne pouvez demander la taille de la cible de la référence. Mais cela ne signifie pas que la référence ne prend pas de stockage -- c'est souvent le cas.Il y a de certain type de moulages que le compilateur sait comment faire implicitement - double int est l'un d'entre eux. Simplement, il supprime la partie décimale. La représentation interne est converti en tant que partie du processus, de sorte que l'affectation fonctionne correctement.
Remarque qu'il y a des valeurs trop grandes pour être correctement convertis. Je ne me souviens pas de ce que les règles pour le cas; il peut être laissé à la discrétion du compilateur.
floor
), ou le nombre entier juste au-dessus (ceil
).Faire un petit programme en C de votre code et suivez les instructions de la section Comment obtenir GCC de générer le code d'assemblée de voir comment le compilateur ne un type de fonte.