Static_cast et reinterpret_cast semblent fonctionner correctement pour la conversion de void * en un autre type de pointeur. Y a-t-il une bonne raison de privilégier l'un plutôt que l'autre?
202
Static_cast et reinterpret_cast semblent fonctionner correctement pour la conversion de void * en un autre type de pointeur. Y a-t-il une bonne raison de privilégier l'un plutôt que l'autre?
Réponses:
Utilisation
static_cast
: c'est la distribution la plus étroite qui décrit exactement quelle conversion est effectuée ici.Il y a une idée fausse selon laquelle l'utilisation
reinterpret_cast
serait une meilleure correspondance, car cela signifie «ignorer complètement la sécurité de type et simplement lancer de A à B».Cependant, cela ne décrit pas réellement l'effet d'un
reinterpret_cast
. Plutôt,reinterpret_cast
a un certain nombre de significations, pour toutes qui soutient que «le mappage effectué parreinterpret_cast
est défini par l' implémentation». [5.2.10.3]Mais dans le cas particulier de la coulée de
void*
àT*
la cartographie est complètement bien défini par la norme; à savoir, pour affecter un type à un pointeur sans type sans changer son adresse.C'est une raison de préférer
static_cast
.De plus, et sans doute plus important, est le fait que chaque utilisation de
reinterpret_cast
est carrément dangereuse car elle convertit tout en n'importe quoi d'autre (pour les pointeurs), alors qu'ellestatic_cast
est beaucoup plus restrictive, offrant ainsi un meilleur niveau de protection. Cela m'a déjà sauvé des bogues où j'ai accidentellement essayé de forcer un type de pointeur dans un autre.la source
C'est une question difficile. D'une part, Konrad fait un excellent point sur la définition de spécification pour reinterpret_cast , bien qu'en pratique cela fasse probablement la même chose. D'un autre côté, si vous effectuez un cast entre des types de pointeurs (comme cela est assez courant lors de l'indexation en mémoire via un char *, par exemple), static_cast générera une erreur de compilation et vous serez de toute façon obligé d'utiliser reinterpret_cast .
En pratique, j'utilise reinterpret_cast car il est plus descriptif de l'intention de l'opération de transtypage. Vous pourriez certainement plaider en faveur d'un opérateur différent pour désigner uniquement des réinterprétations de pointeurs (qui garantissaient la même adresse renvoyée), mais il n'y en a pas dans la norme.
la source
reinterpret_cast
!Je suggère d'utiliser toujours le casting le plus faible possible.
reinterpret_cast
peut être utilisé pour lancer un pointeur sur afloat
. Plus le plâtre est cassant la structure, plus il faut d'attention pour l'utiliser.Dans le cas
char*
contraire, j'utiliserais une fonte de style C, jusqu'à ce que nous en ayonsreinterpret_pointer_cast
, car elle est plus faible et rien d'autre ne suffit.la source
float f = *reinterpret_cast<const float*>(&p);
float
, ce qui est faux. Les moulages d'expressionvoid **
àconst float *
, et utilise ensuite une opération de déréférencement ( ce qui est une distribution), pour convertirconst float *
àfloat
.Ma préférence personnelle est basée sur l'alphabétisation du code comme ceci:
ou
Ils font tous les deux la même chose à la fin, mais static_cast semble plus approprié dans un environnement d'application intermédiaire, tandis que la réinterprétation de la distribution ressemble plus à quelque chose que vous verriez dans une bibliothèque de niveau inférieur à mon humble avis.
la source