2

外部函数接口允许 haskell 与 C 世界一起工作。现在 Haskell 端允许使用Storable实例处理指针。因此,例如,如果我在 C 世界中有一个整数数组,那么在 haskell 世界中的一个合理表示将是Ptr Int. 现在假设我要翻译 C 表达式a[0] = a[0] + 1。在 haskell 方面做到这一点的唯一方法是窥视 int ,然后戳回加法的结果。这种方法的问题是因此创建了一个临时值。(我不确定优化编译器是否总是可以避免这样做)

现在大多数人可能认为这种效果是无害的,但是想想Pointer对象包含一些敏感数据的情况。我在 c 端创建了这个指针,它始终保证它的内容永远不会被换出内存(使用 mlock 系统调用)。现在在 haskell 端查看结果不再保证敏感数据的安全性。

那么在haskell世界中避免这种情况的最佳方法应该是什么?有没有其他人在haskell中遇到过类似的低级指针操作问题。

4

1 回答 1

3

我刚刚用代码构建了一个测试用例:

foo :: Ptr CInt -> IO ()
foo p = peek p >>= poke p ∘ (+1)

并使用 GHC 7.6.3-fllvm -O2 -ddump-asm我看到了相关说明:

0x0000000000000061 <+33>:    mov    0x7(%r14),%rax
0x0000000000000065 <+37>:    incl   (%rax)

因此,它将一个地址加载到该地址rax并增加该地址的内存。似乎是您在其他语言中会得到的,但让我们看看。

对于 C,我认为公平的比较是:

void foo(int *p)
{
    p[0]++;
}

结果是:

0x0000000000000000 <+0>:     addl   $0x1,(%rdi)

所有这一切,我坦率地承认,我不清楚你在担心什么,所以我可能错过了你的观点,并且这样做解决了错误的事情。

于 2013-08-24T14:05:06.310 回答