debugging - `traceIO` 和 `hPutStrLn stderr` 有什么区别?

标签 debugging haskell

查看 traceIO 的描述,我觉得它的作用正是hPutStrLn stderr做。但是,当我查看它的源代码时:

traceIO :: String -> IO ()
traceIO msg = do
    withCString "%s\n" $ \cfmt -> do
     -- NB: debugBelch can't deal with null bytes, so filter them
     -- out so we don't accidentally truncate the message.  See Trac #9395
     let (nulls, msg') = partition (=='\0') msg
     withCString msg' $ \cmsg ->
      debugBelch cfmt cmsg
     when (not (null nulls)) $
       withCString "WARNING: previous trace message had null bytes" $ \cmsg ->
         debugBelch cfmt cmsg

它似乎使用了一个名为 debugBelch 的外部例程。 ,我没有找到任何关于它的文档。那么traceIO 是什么意思? hPutStrLn stderr 做不到的事?

最佳答案

我能想到的一件事是,它可以确保字符串作为一个单元打印,内部没有任何其他跟踪消息。事实上,一个实验似乎证实了这一点:

Prelude Debug.Trace System.IO> traceIO $ "1" ++ trace "2" "3"
2
13
Prelude Debug.Trace System.IO> hPutStrLn stderr $ "1" ++ trace "2" "3"
12
3

另一个区别是它似乎删除了无法安全打印到 stderr 的字符:
Prelude Debug.Trace System.IO> hPutStrLn stderr "\9731"
*** Exception: <stderr>: hPutChar: invalid argument (invalid character)
Prelude Debug.Trace System.IO> traceIO "\9731"

Prelude Debug.Trace System.IO> 

正如@dfeuer 提醒我的那样,这些功能都不是不可能用 Haskell 编写的。所以决定因素可能是: debugBelch 已经是预定义的 C 函数,使用了 all over the place在 GHC 的运行时系统中,它是用 C 和 C--而不是 Haskell 编写的。

关于debugging - `traceIO` 和 `hPutStrLn stderr` 有什么区别?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33059675/

相关文章:

c++ - 为什么在Visual Studio Code中将 “C/C++:”插入我的task.json文件的标签中?

haskell - 为长度索引列表实现 zipper

haskell - 在 Agda 中研究 Peano Axioms 并遇到了一些症结

haskell - 为什么前奏曲中的 `iterate` 不喜结连理?

cocoa - Xcode 项目中的重复符号构建错误

c++ - GDB 回溯未显示正确信息

c++ - winbase::LoadLibrary() 是否加载 .pdbs?

algorithm - Haskell 中惰性求值和严格求值的比较

haskell - 为什么没有办法在 Haskell 中推导出 Applicative Functor?

xCode 4.3 在暂停或断点处崩溃