Pourquoi ne puis-je pas reinterpret_cast uint int?
Voici ce que je veux faire:
const int64_t randomIntNumber = reinterpret_cast<int64_t> (randomUintNumber);
Où randomUintNumber est de type uint64_t
.
L'erreur est (MSVC 2010):
error C2440: 'reinterpret_cast' : impossible de convertir de 'const un uint64_t'
'int64_t' 1> la Conversion est valable de conversion standard,
qui peut être effectuée implicitement ou par l'utilisation de static_cast, de style C
fonte ou de la fonction de style de fonte
Pourquoi ne pas compiler? les deux types ont la même longueur en bits, n'est-ce pas ce que reinterpret_cast est prévu pour?
Si vous pouviez liste les erreurs que vous obtenez, nous pourrions plus facilement dire pourquoi il ne compile pas.
my bad, a élargi la question.
my bad, a élargi la question.
OriginalL'auteur Violet Giraffe | 2013-01-31
Vous devez vous connecter pour publier un commentaire.
Parce que ce n'est pas ce
reinterpret_cast
est pour. Tous les permis de conversions avecreinterpret_cast
impliquent des pointeurs ou des références, à l'exception d'un entier ou d'un type enum peut êtrereinterpret_cast
à lui-même. Tout ceci est défini dans la norme,[expr.reinterpret.cast]
.Je ne suis pas certain de ce que vous essayez d'atteindre ici, mais si vous voulez
randomIntNumber
avoir la même valeur querandomUintNumber
, puis faireSi cela se traduit par un avertissement du compilateur, ou si vous voulez juste pour être plus explicite, alors:
Le résultat de la fonte a la même valeur que l'entrée si
randomUintNumber
est à moins de 263. Sinon, le résultat est la mise en œuvre défini, mais j'attends de tous connu des implémentations qui sontint64_t
vont le définir à faire la chose la plus évidente: le résultat est équivalent à l'entrée modulo 264.Si vous voulez
randomIntNumber
d'avoir le même bit-motifrandomUintNumber
, alors vous pouvez faire ceci:Depuis
int64_t
est garanti à utiliser en complément à deux de la représentation, vous espère que la mise en œuvre définitstatic_cast
pour avoir le même résultat que cela de l'extérieur de la plage de valeurs deuint64_t
. Mais ce n'est pas vraiment garanti dans la norme, autant que je sache.Même si
randomUintNumber
est une constante de compilation, malheureusement, icirandomIntNumber
est pas une constante de compilation. Mais alors, de quelle façon "aléatoire" est une constante de compilation? 😉Si vous avez besoin de travailler autour de cela, et vous n'avez pas confiance en la mise en œuvre doit être raisonnable sur la conversion hors de la portée des valeurs non signées de types signés, alors quelque chose comme ceci:
Maintenant, je suis en faveur de l'écriture véritablement code portable si possible, mais même si je pense que cela confine à la paranoïa.
Btw, vous pourriez être tenté d'écrire ceci:
ou, de manière équivalente:
Cela n'est pas garanti, car bien que là où ils existent
int64_t
etuint64_t
sont garantis d'être un type signé et un type non signé de la même taille, ils ne sont pas assurés d'être les entiers signés et non signés versions d'une norme de type entier. Donc, il est spécifique à l'implémentation de savoir si ou non ce code viole stricte de l'aliasing. Code qui viole stricte de l'aliasing a un comportement indéfini. Ce qui suit ne pas violer stricte de l'aliasing, et est OK à condition que le motif de bits dansrandomUintNumber
est une représentation valide d'une valeur delong long
:Donc sur des implémentations où
int64_t
etuint64_t
sont typedefs pourlong long
etunsigned long long
, puis monreinterpret_cast
est OK. Et comme avec la mise en œuvre de conversion définis par des valeurs de types signés, vous attendre que la chose la plus sensée pour les implémentations à faire est de les rendre correspondant signé/non signé types. Donc, comme lestatic_cast
et la conversion implicite, vous vous attendez à ce qu'il fonctionne dans n'importe quelle mise en œuvre, mais elle n'est pas effectivement garanti.OriginalL'auteur Steve Jessop
Utilisation
static_cast
dans ces cas. Je suppose que la langue des designers dans toute leur sagesse, a décidé qu'il n'est pas considéré comme "dangereux suffisants" pour justifier unereinterpret_cast
.OriginalL'auteur sheu
Non, il n'est pas.
reinterpret_cast
est principalement destiné à réinterpréter un existant bits de stockage comme un type différent qu'il ne l'est. Beaucoup de ces interprétations est dépendant de l'implémentation, et les listes standard spécifique (plutôt longue à citer ici) liste de choses qui peut être fait avec unereinterpret_cast
(principalement la conversion entre les différents pointeur/types de référence), mais il dit:Dans votre cas, vous voudrez probablement une conversion de types, et pas une réinterprétation de stockage existant. Utilisation
static_cast
à cette fin.Si vous voulez relire un certain stockage comme un type différent, alors vous devriez relire jeter un pointeur de stockage. Sachez cependant que vous entrez IB/UB terre ici, surtout si vous êtes un déréférencement le résultat.
Comment ai-je pu oublier... C'est exactement comment je l'ai résolu ce problème, la dernière fois que j'ai rencontré (en jetant un pointeur vers le type de cible et de déréférencement). Où exactement IB/UB émerger ici?
le potentiel de l'AC est en raison de la rigidité de l'aliasing, voir ma réponse.
OriginalL'auteur PlasmaHH
À Partir De C++11(N3376) 5.2.10.1:
La seule conversion de type intégral de type intégral autorisé est enfait si les types sont identiques.
D'autres impliquent des pointeurs.
OriginalL'auteur Karthik T
reinterpret_cast
est utilisé pour réinterpréter le stockage de l'objet comme un objet différent. Si vous ne voulez pas passer par libellé standard, vous pouvez trouver tout ce quereinterpret_cast
peut faire ici. Généralement, vous pouvez vous souvenir que vous avez à travailler avec les types pointeur.Donc, si vous voulez vraiment à réinterpréter les bits utilisés pour votre
uint64_t
commeint64_t
, puis le faire:Toutefois, si vous ne voulez convertir que l'objet, la préservation de sa valeur, si possible ... il suffit de faire ce que le compilateur suggère et l'utilisation
static_cast
à la place.reinterpret_cast
est que limité dans ses usages. Merci pour l'affichage de la bidouille, trop 🙂OriginalL'auteur Fiktik
Parce que ni le type est un pointeur.
Pourquoi cette question? Si ils étaient des pointeurs, peut-être que ça aurait de l'importance qu'ils ont fait pour les choses de la même taille, mais ils ne sont pas des pointeurs.
Non,
reinterpret_cast
est pour pointeur de jette. Vous pourriez faire ce que vous voulez en mettant un&
à l'intérieur de la fonte et un*
à l'extérieur. C'est ce que réinterpréter le casting est pour.Il s'agit d'un malentendu au sujet de
reinterpret_cast
. Il n'a pas, sur le plan conceptuel, faire un bit à bit réinterprétation (bien que sur des plates-formes communes, il 'arrive'). Par exemple, la norme C++ (5.2.10) dit qu'avec reinterpret_cast, un "pointeur peut être explicitement converti à n'importe quel type intégral assez grand pour les contenir." -- qui inclut plus les types intégraux. Et, il dit explicitement qu'il "pourrait, ou ne pourrait pas, de produire une représentation différente de la valeur d'origine".Lors de l'utilisation des résultats d'une
reinterpret_cast
, la longueur en bits de l'souligné (ou référencé) objets de questions. Le bit longueur des pointeurs eux-mêmes n'est pas pertinente: vous pouvezreinterpret_cast
entrechar*
etint*
, même lorsquechar*
etint*
ont des tailles différentes (comme elles ont parfois fait sur des machines plus anciennes).OriginalL'auteur David Schwartz