Haskell reallyUnsafePtrEquality#在没有字段的构造函数上
我的理解是,没有字段的类型的构造函数是“静态分配的”和GHC,并且 如果这是正确的,那么我希望像Haskell reallyUnsafePtrEquality#在没有字段的构造函数上,haskell,ghc,Haskell,Ghc,我的理解是,没有字段的类型的构造函数是“静态分配的”和GHC,并且 如果这是正确的,那么我希望像False和Nothing这样的on值的使用是非常安全的(没有误报或误报),因为它们只能表示为指向该构造函数的单个实例的相同指针 我的推理正确吗?在不久的将来的GHC版本中,是否有任何潜在的问题或理由怀疑这可能会变得不安全?我实际上设法让really unsafeptrequality做了错误的事情 下面是我的最小代码示例 {-# LANGUAGE MagicHash #-} import GHC.P
False
和Nothing
这样的on值的使用是非常安全的(没有误报或误报),因为它们只能表示为指向该构造函数的单个实例的相同指针
我的推理正确吗?在不久的将来的GHC版本中,是否有任何潜在的问题或理由怀疑这可能会变得不安全?我实际上设法让
really unsafeptrequality
做了错误的事情
下面是我的最小代码示例
{-# LANGUAGE MagicHash #-}
import GHC.Prim
-- Package it up nicely
ptrCmp :: a -> a -> Bool
ptrCmp a b = case (reallyUnsafePtrEquality# a b) of
0# -> False
1# -> True
main = do
b <- readLn
let a = if b then Nothing else Just ()
a' = Nothing
print $ a == a' -- Normal
print $ ptrCmp a a' -- Evil
所以。。。是的,
真正的不安全性
仍然是邪恶的。可能是真的。另一方面,似乎对于没有字段的构造函数来说,与无聊的旧(==)
相比,性能优势将非常小……@DanielWagner我的实际用例是在盒式引用上使用新的CAS primops。当使用原子primops
库时,我希望能够缓存无票
(例如),并确保它不会过时。您可能还需要注意插件等。不,我的意思是,将代码加载到正在运行的Haskell程序中的插件可能会得到它们自己的空构造函数副本。我不知道是哪种方式,但这是我担心的事情。我很确定空构造函数指针只有在GC生存之后才会被重新写入指向.TEXT的位置。它们的初始分配和指针仍然指向动态分配的空间,这使得这里提出的技术不安全。值得注意的是,我完全不知道为什么会发生这种情况。只是通过愚蠢的运气和尝试病理学案例来推翻这个猜测。如果有人能给我点启示的话……哦,太棒了,谢谢你。当我提出它可能是“非常安全的”时,我有点超前了,因为我们至少还存在将thunk与值进行比较的问题,以及内联可能导致的所有复杂性。我猜这里会发生类似的事情,但我不知道到底是什么……我认为使用如果b那么a'else()
肯定会成功。我错了。这确实很邪恶:)奇怪的是,在a
中添加一个bang模式会使ptrCmp
返回真值。“我想我理解为什么没有爆炸模式它就不能工作:它是邪恶的。”本贾米尼奥格森说,我觉得这个解释并不完整;不打印(a==a')
强制a
和a'
,在调用ptrCmp
时将它们保留为非thunks?
$ ghc --version
The Glorious Glasgow Haskell Compilation System, version 7.8.2
$ ghc unsafe.hs
$ ./unsafe
True
True
False