web-dev-qa-db-ja.com

C ++ 20 bit_castとreinterpret_cast

ISO C++委員会の前回の会議によると、C++ 20標準で bit-cast が導入される予定です。

reinterpret_castタイプエイリアスルール のためにこのジョブに適していないことを知っていますが、私の質問は、オブジェクトをビットのように扱うためにreinterpret_castを拡張しないことを選択した理由ですシーケンス表現で、この機能を新しい言語構成要素として提供することをお勧めしますか?

19
bogdan tudose

まあ、1つの明白な理由があります。それは、bit_castが行うすべてのことを行うわけではないためです。コンパイル時にメモリを割り当てることができるC++ 20の世界でも、constexpr関数ではreinterpret_castは禁止されています。 bit_castの明確な目標の1つは、コンパイル時に次のようなことを実行できるようにすることです。

さらに、constexpr自体はmemcpyではないため、constexprビットキャスト関数を実装することは現在不可能です。提案された関数をconstexprとしてマークしても、memcpyconstexprになる必要はありませんが、コンパイラのサポートが必要です。これにより、実装は独自の内部ソリューションを自由に使用できます(たとえば、LLVMにはbitcastオペコードがあります)。

これで、reinterpret_castのこの特定の使用法をconstexprコンテキストに拡張できると言えます。しかし、それはルールを複雑にします。 reinterpret_castconstexprコード期間で使用できないことを単に知る代わりに、使用できないreinterpret_castの特定の形式を覚えておく必要があります。

また、実際的な懸念もあります。 reinterpret_castルートを使用したい場合でも、std::bit_castはライブラリ関数です。また、コンパイラーのサポートを受けたとしても、言語機能よりも委員会を通じてライブラリ機能を入手する方が常に簡単です。

次に、より主観的なものがあります。 reinterpret_castは通常、本質的に危険な操作と見なされ、何らかの方法で型システムを「だます」ことを示します。対照的に、bit_castはそうではありません。既存のオブジェクトから値表現をコピーするかのように、新しいオブジェクトを生成しています。これは低レベルのツールですが、型システムを混乱させるツールではありません。したがって、「安全な」操作を「危険な」操作と同じように綴ることは奇妙です。

実際、同じように綴った場合、なぜこれが合理的に明確に定義されているのかという疑問が生じ始めます。

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

しかし、これはどういうわけか悪いです:

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

そして確かに、言​​語弁護士や厳密なエイリアシング規則に詳しい人なら、なぜ後者が悪いのか理解するでしょう。しかし、素人の人にとって、ビット変換を行うためにreinterpret_castを使用しても問題ない場合、reinterpret_castを使用してポインタ/参照を変換し、既存のオブジェクトを変換されたタイプ。

さまざまなツールのスペルは異なります。

21
Nicol Bolas