How does this C program compile and run with two main functions? How does this C program compile and run with two main functions? c c

How does this C program compile and run with two main functions?


Quoting ld(1):

The linker will search an archive only once, at the location where it is specified on the command line. If the archive defines a symbol which was undefined in some object which appeared before the archive on the command line, the linker will include the appropriate file(s) from the archive.

When linking 2main, main symbol gets resolved before ld reaches -lstatic, because ld picks it up from prog.o.

When linking 1main, you do have undefined main by the time it gets to -lstatic, so it searches the archive for main.

This logic only applies to archives (static libraries), not regular objects.When you link prog.o and static.o, all symbols from both objects are included unconditionally, so you get a duplicate definition error.


When you link a static library (.a), the linker only searches the archive if there were any undefined symbols tracked so far. Otherwise, it doesn't look at the archive at all. So your 2main case, it never looks at the archive as it doesn't have any undefined symbols for making the translation unit.

If you include a simple function in static.c:

#include <stdio.h>void fun(){      printf("This is fun\n");}   int main(){      printf("Main in static.c\n");}

and call it from prog.c, then linker will be forced to look at the archive to find the symbol fun and you'll get the same multiple main definition error as linker would find the duplicate symbol main now.

When you directly compile the object files(as in gcc a.o b.o), the linker doesn't have any role here and all the symbols are included to make a single binary and obviously duplicate symbols are there.

The bottom line is that linker looks at the archive only if there are missing symbols. Otherwise, it's as good as not linking with any libraries.


After the linker loads any object files, it searches libraries for undefined symbols. If there are none, then no libraries need to be read. Since main has been defined, even if it finds a main in every library, there is no reason to load a second one.

Linkers have dramatically different behaviors, however. For example, if your library included an object file with both main () and foo () in it, and foo was undefined, you would very likely get an error for a multiply defined symbol main ().

Modern (tautological) linkers will omit global symbols from objects that are unreachable - e.g. AIX. Old style linkers like those found on Solaris, and Linux systems still behave like the unix linkers from the 1970s, loading all of the symbols from an object module, reachable or not. This can be a source of horrible bloat as well as excessive link times.

Also characteristic of *nix linkers is that they effectively search a library only once for each time it is listed. This puts a demand on the programmer to order the libraries on the command line to a linker or in a make file, in addition to writing a program. Not requiring an ordered listing of libraries is not modern. Older operating systems often had linkers that would search all libraries repeatedly until a pass failed to resolve a symbol.