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

为何TinyCC在32位模式下无法链接标准C运行时函数,64位模式却正常?

TinyCC 32位模式编译调用msvcrt.dll的程序时出现未定义符号错误

当使用TinyCC的32位模式(-m32)编译调用msvcrt.dll中CRT函数/符号的程序时,编译会失败。执行以下命令:

tcc.exe -std=c11 -Wall -Werror -Wl,-subsystem=console -m32 .\main.c

会得到错误:
tcc: error: undefined symbol '_iob', missing __declspec(dllimport)?

该问题仅在-m32模式下出现,切换到64位模式(-m64)时,使用以下命令可正常编译运行:

tcc.exe -std=c11 -Wall -Werror -Wl,-subsystem=console -m64 .\main.c

问题细节

_iob并非唯一未解析的符号,printf、freopen、freopen_s等几乎所有CRT函数都会出现链接失败的情况。

已尝试的解决方法

所有以下操作均无法解决问题,TCC仍报相同的未定义符号错误:

  • 添加-lmsvcrt编译参数,或在代码中使用#pragma comment(lib, "msvcrt")
  • 用_declspec(dllimport)或__attribute__((dllimport))修饰符号
  • 尝试-static、-shared等编译选项
  • 对C:\Windows\SysWow64\msvcrt.dll(甚至更早版本如msvcrt40.dll)执行tcc -impdef命令生成导入库
  • 修改-I和-L路径指向C:/Windows/SysWow64

验证信息

已通过DUMPBIN.exe确认,32位和64位版本的msvcrt.dll均导出了_iob及相关CRT符号。

示例代码

// #pragma comment(lib, "msvcrt")
// __attribute__((dllimport)) extern __declspec(dllimport) FILE _iob[];

#include <windows.h>

// 定义_MSVCRT_会使MinGW的stdio.h使用_iob而非_imp___iob;前者才在msvcrt.dll中定义。
// 尽管32位和64位版本的该dll都导出了_iob,TinyCC仍无法在前者中找到它。
#define _MSVCRT_
#include <stdio.h>

void main() {
    // AllocConsole()及kernel32.dll或user32.dll中的几乎所有函数,在-m32和-m64模式下都能正常工作;
    // 只有msvcrt.dll会给TinyCC带来问题。
    AllocConsole();

    // 任何CRT函数(如freopen、freopen_s、printf等)仅在-m32模式下无法正确链接;-m64模式正常。
    // 即使修改-I和-L路径指向C:/Windows/SysWow64,或使用tcc.exe -impdef从其中生成.def文件,
    // TCC仍无法找到_iob及其他符号。使用#pragma comment(lib, "msvcrt")或-lmsvcrt也毫无帮助。
    // 即使设法让TCC停止抱怨缺失符号,它也只会生成空白的IAT.printf或IAT.freopen,导致段错误。
    freopen("CONOUT$", "w", stdout);
    printf("This only compiles (and prints) under TCC in 64-bit mode.");
}

总结

-m32模式下的错误不受-std、-shared、-static、-lmsvcrt、-subsystem等编译选项影响,推测这可能是TinyCC 0.9.27(Win32和Win64版本)本身的bug。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.16 02:23:16