web-dev-qa-db-fra.com

C ++ 20 bit_cast vs reinterpret_cast

Selon la dernière réunion du comité ISO C++, bit-cast sera introduit dans la norme C++ 20.

Je le sais reinterpret_cast ne convient pas à ce travail en raison de type aliasing rules mais ma question est pourquoi ont-ils choisi de ne pas étendre le reinterpret_cast pour traiter l'objet comme une représentation de séquence de bits et préférer donner cette fonctionnalité comme une nouvelle construction de langage?

19
bogdan tudose

Eh bien, il y a une raison évidente: parce qu'il ne ferait pas tout ce qui bit_cast Est-ce que. Même dans le monde C++ 20 où nous pouvons allouer de la mémoire au moment de la compilation, reinterpret_cast est interdit dans les fonctions constexpr. L'un des objectifs explicites de bit_cast est de pouvoir faire ce genre de choses au moment de la compilation:

De plus, il est actuellement impossible d'implémenter une fonction constexpr bit-cast, car memcpy lui-même n'est pas constexpr. Le fait de marquer la fonction proposée comme constexpr ne nécessite ni n'empêche memcpy de devenir constexpr, mais nécessite la prise en charge du compilateur. Cela laisse les implémentations libres d'utiliser leur propre solution interne (par exemple, LLVM a un opcode bitcast).

Maintenant, vous pouvez dire que vous pouvez simplement étendre cette utilisation spécifique de reinterpret_cast à constexpr contextes. Mais cela complique les règles. Au lieu de simplement savoir que reinterpret_cast ne peut pas être utilisé pendant constexpr période de code, vous devez vous souvenir des formes spécifiques de reinterpret_cast qui ne peut pas être utilisé.

En outre, il existe des préoccupations pratiques. Même si vous vouliez aller le reinterpret_cast route, std::bit_cast est une fonction de bibliothèque. Et il est toujours plus facile d'obtenir une fonctionnalité de bibliothèque via le comité qu'une fonctionnalité de langue, même si elle recevrait un certain support du compilateur.

Ensuite, il y a les choses plus subjectives. reinterpret_cast est généralement considéré comme une opération intrinsèquement dangereuse, révélatrice d'une "tromperie" du système de caractères d'une manière ou d'une autre. Par contre, bit_cast n'est pas. Il génère un nouvel objet comme s'il copiait sa représentation de valeur à partir d'un objet existant. C'est un outil de bas niveau, mais ce n'est pas un outil qui dérange le système de type. Il serait donc étrange d'épeler une opération "sûre" de la même manière que vous en épelez une "dangereuse".

En effet, si vous les avez orthographiés de la même manière, cela commence à soulever des questions quant à la raison pour laquelle cela est raisonnablement bien défini:

float f = 20.4f;
int i = reinterpret_cast<int>(f);

Mais c'est en quelque sorte mauvais:

float f = 20.4f;
int &i = reinterpret_cast<int &>(f);

Et bien sûr, un juriste spécialisé dans les langues ou quelqu'un connaissant la règle de pseudonyme stricte comprendrait pourquoi cette dernière est mauvaise. Mais pour le profane, s'il est bon d'utiliser reinterpret_cast pour faire une conversion de bits, on ne sait pas pourquoi il est mal d'utiliser reinterpret_cast pour convertir des pointeurs/références et interpréter un objet existant comme un type converti.

Différents outils doivent être orthographiés différemment.

21
Nicol Bolas