C Programming – Do All Programs Need to Load a Library?

clibrarieslinux

With a program like

int main()
{
   return 0;
}
  • and you statically link, will some library on your system be linked into the final binary.
  • and you dynamically link, will a library be loaded when it's run?

In essence, is a library always required for even the simplest programs, if so why? I ask because I thought the canonical entry point for anything that wants to be executed is actually _start (which I thought was in a library, namely glibc). Maybe I don't understand what _start really does with regard to setting things up, so any pointers there would be helpful too.

Best Answer

If you want to write your program in standard portable C, you need of course some runtime that calls the main() function in the first place.

But if you don't care about that, you can dispense with any library, and do system calls directly via inline assembly. Eg. for x86-64:

$ cat q.c
#include <sys/syscall.h>
void _start(void){
        __asm__( "syscall" : : "D"(0), "a"(SYS_exit) );
}
$ cc -O2 -static -nostdlib -nostartfiles -Wall q.c -o q
$ strace ./q
execve("./q", ["./q"], 0x7fffc72d8d20 /* 39 vars */) = 0
exit(0)                                 = ?
+++ exited with 0 +++

You have to do at least one system call, namely _exit(2), unless exit-by-crashing is acceptable for a "simplest program", in which case an empty file will do, too ;-):

$ > foo.c
$ cc -static -nostdlib -nostartfiles -Wall foo.c -o ./foo
/usr/bin/ld: warning: cannot find entry symbol _start; defaulting to 0000000000401000
$ ./foo
Segmentation fault

I thought the canonical entry point for anything that wants to be executed is actually _start

there's nothing canonical about it; _start is the default name the linker will use; you can point it elsewhere with the -e sym option (-Wl,-e,sym with gcc).

Related Question