1. For a C or assembly program that does not require any other library, will linking be necessary? In other words, will conversion from C to Assembly and/or from Assembly to an object file be enough without being followed by linking?

    If linking is still needed, what will it do, given that there is just one object file which doesn't need a library to link to?

  2. Relatedly, how different are object files and executable files, given that in Linux, both have file format ELF?

    Are object files those ELF files that are not runnable?

    Are there some executable files that can be linked to object files? If yes, does it mean dynamical linking of executables to shared libraries?

3 Answers 3


First of all, it's really hard for any non-trivial program to 'not require any other library'. Remember that glibc and the startup code calling main() are libraries too.

But yes, even in this case you need the linker, just because the compiler/assembler typically don't handle ELF format (or any executable format). Precisely because usually you'll have to link with some libraries, so why should it bother to compile to ELF? It's better to focus on linkable-code formats and leave the executable formats to the linker.

PS: I forgot that .so is also a variant of ELF. But it still doesn't change the fact that it's a different subformat and the executable details are just not included in most compiler/assembers.

Yes, it's quite possible for a single tool to compile directly to executable, but that just means that it includes both the compiler and the linker in a single command. Why would it consider the (very) special case when you won't add any other code? It's far more logical to do it in the linker, after all you'll need it in %99.9 cases.

  • Thanks! (1) If a program has nothing inside main(){}, what library does the program need to link to? (2) In this case, do you mean that linker's job is to transform an object file to an executable file? (3) How object files and executable files are different? Any references? I only know they are both ELF format in Linux.
    – Tim
    Commented Aug 1, 2011 at 5:05
  • @Tim: it will need to link with a library called (usually) crt0.o. This library contains the "real" entry point for the program and sets up the environment before calling main. Typically it does things like parsing the command line, setting errno to 0, etc. Commented Aug 1, 2011 at 22:14
  • @Dean: Thanks! What about assembly? If an assembly program does not call any other library, is assembling enough without linking?
    – Tim
    Commented Aug 1, 2011 at 22:18

It depends on the operating system. In general, though, you need something to convert the object file into an executable file. Object files are usually designed to be the input into the linker, and not to be run directly.

There are very few, if any, useful programs that don't need to have libraries linked in with them. (Maybe static, maybe dynamic, but without the library infrastructure, you're not going to get much useful work done.)


Your program will (at the minimum) need to link to a loader in order run. Consider the following trivial code:

tpost@tpost-desktop:~$ cat count.c
int main(void)
        unsigned int i;

        for (i = 0; i < 10; i++) {;;}

        return 0;

Now we compile it:

tpost@tpost-desktop:~$ gcc -Wall -o count count.c

And now we examine what the linker did:

    linux-gate.so.1 =>  (0x002b5000)
    libc.so.6 => /lib/tls/i686/cmov/libc.so.6 (0x00482000)
    /lib/ld-linux.so.2 (0x00241000)

    Version information:
            libc.so.6 (GLIBC_2.0) => /lib/tls/i686/cmov/libc.so.6
            ld-linux.so.2 (GLIBC_PRIVATE) => /lib/ld-linux.so.2
            ld-linux.so.2 (GLIBC_2.3) => /lib/ld-linux.so.2
            ld-linux.so.2 (GLIBC_2.1) => /lib/ld-linux.so.2

Of interest is the fact that ldd found no physical file for linux-gate.so.1 and ld-linux.so.2, this is because both of them are virtual dynamic shared objects that reside in every process address space. The shared objects themselves are exposed by the kernel and contain the code needed to actually load the program, which works in conjunction with the system C library.

Let's statically link this, shall we?

tpost@tpost-desktop:~$ gcc -static -Wall -o count count.c
tpost@tpost-desktop:~$ ldd -v count
        not a dynamic executable

I haven't eliminated the linking dependency here, all I've done is taken the loader code and system C library and made them part of the executable. That seems somewhat silly, because my executable no longer uses a perfectly good copy of that code which is already in memory.

You could write your own loader code and not use what's provided by the system C library, but you aren't going to lose the dependencies on the kernel loader itself.

This is a very Linux oriented example, but it's all I have available to me to illustrate the point :)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.