You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Haskell中通过ccall调用C函数时printf无法输出的原因是什么?

问题:为何C代码中的printf输出未出现在Haskell程序运行结果中?

Haskell代码

{-# LANGUAGE ForeignFunctionInterface #-}

import GHC.Ptr
import Foreign
import Foreign.C
import Control.Monad

foreign import ccall unsafe "fibonacci.c fib" c_fib :: Int -> Int
example :: IO ()
example = print (c_fib 5)     
main = example

C代码(fibonacci.c)

#include <stdio.h>

int fib(const int n) {
    if (n == 1) {
        printf("here");
        return 1;
    }
    else {
        return n*fib(n-1);
    }
}

运行结果

120 // does not print "here"

解答

这是C标准库的输出缓冲机制导致的问题:

  • printf默认采用行缓冲模式,只有当输出内容包含换行符\n、缓冲区被手动刷新,或是程序正常触发缓冲区刷新逻辑时,缓冲区里的内容才会被输出到终端。
  • 你的代码里printf("here")没有加换行,Haskell程序调用完C函数后直接执行print并退出,此时C的输出缓冲区还没来得及刷新,里面的"here"就随着进程结束被丢弃了。

解决办法有两种:

  1. 给printf添加换行符:
    printf("here\n");
    
  2. 在printf后手动刷新标准输出缓冲区:
    printf("here");
    fflush(stdout);
    

另外补充:原C代码漏掉了#include <stdio.h>头文件,虽然部分编译器允许隐式声明,但规范写法必须加上,否则printf和fflush的行为可能处于未定义状态。


内容的提问来源于stack exchange,提问作者kesarling

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.15 17:52:45