No library specified, yet printf gets linked into

2019-08-29 08:16发布

问题:

I have the following code:

#include <stdio.h>

int main()
{
    printf ("hello world\n");
    return 0;
}

Using MSVC++ 10.0 on Windows 7 x86, I compile it on the command line as follows:

cl.exe simple.cpp

This produces simple.exe (the compiler automatically calls the linker) and the executable displays the "hello world" message as expected. When I look into the executable w/ depends.exe, it shows kernel32.dll as the only dependency. When I dumpbin the contents of kernel32.dll library, there is no printf shown.

Does VC++ employ some sort of optimization so that printf is somehow included directly into the final executable? If so, how, and is it documented anywhere?

Many thanks in advance -

Todd

回答1:

libc.lib is no longer used.

The options for static or dynamic inclusion of C runtime library (CRT) on VC++ 10 are documented here. You can select the one you need/desire in Project Options.



回答2:

MS VC embeds the name of a "default" library into most object files. That library (or those libraries) will be linked unless you specify otherwise with the linker's -nodefaultlib option. If you use that by itself, it doesn't link any default libraries. You can also specify something like -nodefaultlib:mylib.lib, in which case it links all the default libraries except those you specify here.

To use your example, if you use:

cl simple.c

It'll compile and link correctly. If, however, you use:

cl simple.c -link -nodefaultlib

You'll get:

simple.obj : error LNK2019: unresolved external symbol printf referenced in function main
LINK : error LNK2001: unresolved external symbol mainCRTStartup
simple.exe : fatal error LNK1120: 2 unresolved externals

Just to be complete, you can also use the compiler's /Zl switch to create the object without any embedding the name of any library. This is intended (primarily) for creating static libraries, so they won't embed the name of a library the conflicts with however you build code that uses your library.



回答3:

printf (actually fprintf to stdout), as well as other "standard" functions malloc, exit etc. are statically linked with libc.lib, that's why you don't see it as a dll anywhere.