我只想知道它在编译时是如何工作的。GHC作为其解释器,使用GMP库来生成和操作非常大的数字,但GHC编译的可执行文件没有第三方GMP库可携带。那么编译器如何保持同样的准确性呢?可执行文件是否有自己的大量操作实现?
如果您采用程序:
main :: IO ()
main = do
x <- readLn :: IO Integer
print $ x + 1
并在带有-v
标志的Linux机器上编译:
$ ghc -v AddOne.hs
然后,您会在详细输出的末尾找到用于将可执行文件链接在一起的gcc
命令:
*** Linker:
gcc -fno-stack-protector -DTABLES_NEXT_TO_CODE '-fuse-ld=gold' ...
这是一条很长的线,但如果你搜索它,你应该会发现(可能在末尾(一组正在链接的外部库:
... -lHSrts -lCffi -lgmp -lm -lrt -ldl -lpthread
-lgmp
在GMP库中存在链接。
您也可以使用ldd
命令来显示可执行文件中对系统GMP库的依赖性:
$ ldd AddOne
...
libgmp.so.10 => /usr/lib/x86_64-linux-gnu/libgmp.so.10 (0x00007fc0da1fa000)
...
至少,在我的系统上是这样的,最近版本的GHC在Stack下运行。如果你发现你的系统上没有GMP依赖性,那可能只是因为它被配置为将所需的GMP代码静态链接到可执行文件中,而不是在运行时动态链接。(例如,我认为在Windows上,GMP代码默认情况下是静态链接的。(
为了使事情稍微复杂一点,可以使用GMP以外的整数库,尽管这需要在编译GHC时完成。该链接中提到的一个替代方案是integer-simple
库,它是大整数运算的Haskell实现,是GHC源树的一部分。因此,在这种特殊情况下,可执行文件将使用其自己的大量操作实现。不过,我认为你不太可能找到一个标准的、预先编译的GHC,它使用了GMP以外的东西。
GHC编译的可执行文件使用GMP实现Integer
。
GHC编译的可执行文件没有第三方GMP库来携带
如果你的意思是GHC编译的可执行文件没有与GMP链接,那你就错了。确实如此。