5

私は と を試していunsafeCoerceましたが、驚くべき動作を見つけました (とにかく私にとって)。Int8Word8

Word80 ~ 255 の範囲の 8 ビットの符号なし数値です。Int8-128..127 の範囲の符号付き 8 ビット数です。

どちらも 8 ビットの数値であるため、相互に強制しても安全であると想定し、8 ビットの値を符号付き/符号なしのように返すだけです。

たとえばunsafeCoerce (-1 :: Int8) :: Word8、値は 255 になると予想しWord8ます (signed int の -1 のビット表現は unsigned int の 255 と同じであるため)。

ただし、強制を実行するとWord8、動作が奇妙になります。

> GHCi, version 7.4.1: http://www.haskell.org/ghc/  :? for help
> import Data.Int
> import Data.Word
> import Unsafe.Coerce
> class ShowType a where typeName :: a -> String
> instance ShowType Int8 where typeName _ = "Int8"
> instance ShowType Word8 where typeName _ = "Word8"

> let x = unsafeCoerce (-1 :: Int8) :: Word8
> show x
"-1"
> typeName x
"Word8"
> show (x + 0)
"255"
> :t x
x :: Word8
> :t (x + 0)
(x + 0) :: Word8

show xここに戻る方法がわかりません"-1"。を見るとmap show [minBound..maxBound :: Word8]、 の可能な値はありませWord8"-1"。また、型が変更されていなくても、数値に 0 を追加すると動作がどのように変わりますか? 奇妙なことに、影響を受けるのはクラスだけであるようにも見えますShow-私のShowTypeクラスは正しい値を返します。

最後に、コードfromIntegral (-1 :: Int8) :: Word8は期待どおりに動作し、255 を返し、show. このコードは、コンパイラによってノーオペレーションに削減できますか?

この質問は、タイプが ghc で低レベルでどのように表現されるかについての好奇心からであることに注意してください。私は実際に自分のコードで unsafeCoerce を使用していません。

4

2 に答える 2

4

を使ってしまったら、何かがおかしいとは言えませんunsafeCoerce。その機能を使えばなんとでもなる。コンパイラはおそらくInt8単語に an を格納し、を使用して、この単語に格納されているものの不変条件unsafeCoerceWord8破ります。fromIntegral変換するために使用します。

Int8usingからWord8usingへの変換は、x86 で ghc を使用fromIntegralする命令に変わります。これは基本的にノーオペレーションです。movzbl

于 2013-04-05T08:41:23.230 に答える