Building a C program should be no rocket science! I recently had to return to this kind of business since many years of absence.
Interestingly I encounter the exact opposite as asked in Why is #include <stdio.h> not required to use printf()?
#if 0
#include <stdio.h>
#endif
void main() { /* Yes, I know! */
printf("Hello, World!\n");
}
I want to compile and link the above example.
If I use the Digital Mars C Compiler all it's gonna take is
dmc -c hello.c
optlink hello.obj,hello.exe
Done.
OK, it was that simple because the DMC toolchain backstage did some work for me.
On the one hand the compiler inserted a hint into the object file saying the external "_printf" can be found in library SNN
0082 COMENT 0 9f 53 4e 4e ..SNN
008b EXTDEF e 5f 5f 61 63 72 74 75 73 65 64 5f 63 6f 6e 0 .__acrtused_con.
7 5f 70 72 69 6e 74 66 0 ._printf.
00a8 PUB386 0 1 5 5f 6d 61 69 6e 0 0 0 0 0 ..._main.....
And on the other hand the linker is searching libraries to satisfy unresolved externals
Loading hello from hello.obj
Searching LIBRARY files
Loading constart from ..\lib\SNN.lib
Loading _printf from ..\lib\SNN.lib
There is the option
-NL no default library
to make the compiler stop doing this additional work. I now get a plain object file.
Hey, and therefore it's no surprise the linker is yelling at me
hello.obj(hello)
Error 42: Symbol Undefined __acrtused_con
hello.obj(hello)
Error 42: Symbol Undefined _printf
Because it's my turn now to tell the linker where to get the missing stuff from
optlink hello.obj,hello.exe,,SNN.lib
Again done.
Now let's use the Microsoft toolchain...
cl -c hello.c
link hello.obj
Boom!
hello.obj : error LNK2019: unresolved external symbol "_printf" in function "_main".
hello.exe : fatal error LNK1120: 1 unresolved external.
For some reason the linker will only produce a hello.exe when the source file includes <stdio.h>.
What kind of "new" magic feature did M$ include in their toolchain?
PS: Somehow the statement in MSDN does not hold true: If you link your program from the command line without a compiler option that specifies a C runtime library, the linker will use the statically linked CRT libraries: libcmt.lib, libvcruntime.lib, and libucrt.lib.