web-dev-qa-db-fra.com

Dois-je utiliser static_cast ou reinterpret_cast lors de la création d'un void *?

Static_cast et reinterpret_cast semblent fonctionner correctement pour convertir void * en un autre type de pointeur. Y a-t-il une bonne raison de favoriser l'un par rapport à l'autre?

175
Andy

tilisation static_cast: c'est la distribution la plus étroite qui décrit exactement la conversion effectuée ici.

Il existe une idée fausse selon laquelle utiliser reinterpret_cast _ conviendrait mieux car cela signifie "ignorer complètement la sécurité du 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 "la cartographie effectuée par reinterpret_cast est défini par la mise en œuvre. ”[5.2.10.3]

Mais dans le cas particulier du casting de void* à T* le mappage est parfaitement défini par la norme; à savoir, assigner 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, le fait que chaque utilisation de reinterpret_cast est carrément dangereux car il convertit n'importe quoi en autre chose (pour les pointeurs), alors que static_cast est beaucoup plus restrictif, offrant ainsi un meilleur niveau de protection. Cela m'a déjà évité des bugs où j'ai accidentellement essayé de contraindre un type de pointeur à un autre.

125
Konrad Rudolph

C'est une question difficile. D'un côté, Konrad fait un excellent point sur la définition de spec pour reinterpret_cast, bien que dans la pratique, il fasse probablement la même chose. Par contre, si vous utilisez différents types de pointeurs (comme c'est souvent le cas lors de l'indexation en mémoire via un caractère *, par exemple), static_cast générera une erreur du compilateur et vous serez forcé. utiliser reinterpret_cast quand même.

En pratique, j'utilise reinterpret_cast car c'est plus descriptif de l'intention de l'opération de conversion. Vous pouvez certainement demander à un autre opérateur de désigner uniquement le pointeur pour réinterpréter (qui garantit la même adresse renvoyée), mais il n'y en a pas dans la norme.

7
Nick

Je suggère d'utiliser toujours le casting le plus faible possible.

reinterpret_cast peut être utilisé pour convertir un pointeur en un float. Plus le casting est en rupture de structure, plus l'attention que cela nécessite d'attirer est grande.

En cas de char*, J'utiliserais le casting de style c, jusqu'à ce que nous ayons quelques reinterpret_pointer_cast, parce que c'est plus faible et que rien d'autre n'est suffisant.

0
Pavel Radzivilovsky