其他人已经对静态链接 CRT 做出了回应。如果您同时还想要一个小的二进制文件,那么最好的选择是完全放弃 CRT,并尽可能只使用 Win32 API 函数。您仍然会得到一些 CRT 代码,最明显的是与启动(即调用的代码main
)和关闭(atexit
处理等)相关的代码,但否则链接器不会链接您不使用的 CRT 函数。
/Zl
您可以通过使用编译器开关完全避免链接 CRT 。但是,这意味着main
它将不再起作用-您需要定义WinMain
(名称无关紧要,但签名必须匹配,并且必须是__stdcall
),并且您必须将WinMain
-like 函数的名称指定为条目通过链接器/entry:
开关点。这将为您节省约 30Kb 的 CRT 代码(在 .cpp 上测试,并带有一个空的main
)。
如果你走后一条路线,你可能还必须处理编译器内在函数的问题。有一些函数名义上由 CRT 定义(并在其头文件中声明),但编译器会对其进行特殊处理,以便它在可能的调用点插入优化的汇编指令 - 示例是memset
、strlen
和中的大量功能<math.h>
;可以在此处找到完整列表。由于您没有 CRT,如果您需要这些功能,或者可以避免使用这些功能,但由于性能提高而更喜欢内在功能(memset
例如,很难做得比#pragma intrinsic
. 例如:
// Contains macros and typedef only, so safe to include without CRT.
// We need it here for size_t.
#include <stddef.h>
extern "C"
{
int abs(int);
void* memset(void*, int, size_t);
}
#pragma intrinsic(abs, memset)
int __stdcall main(void*, void*, char*, int)
{
char tmp[10];
memset(tmp, abs(-123), 10);
return 0;
}
上面可以编译:
cl /c /Zl foo.cpp
link /entry:main foo.obj