Today, while working with one custom library, I found a strange behavior. A static library code contained a debug main()
function. It wasn't inside a #define
flag. So it is present in library also. And it is used link to another program which contained the real main()
.
When both of them are linked together, the linker didn't throw a multiple declaration error for main()
. I was wondering how this could happen.
To make it simple, I have created a sample program which simulated the same behavior:
$ cat prog.c #include <stdio.h> int main() { printf("Main in prog.c\n"); } $ cat static.c #include <stdio.h> int main() { printf("Main in static.c\n"); } $ gcc -c static.c $ ar rcs libstatic.a static.o $ gcc prog.c -L. -lstatic -o 2main $ gcc -L. -lstatic -o 1main $ ./2main Main in prog.c $ ./1main Main in static.c
How does the "2main" binary find which main
to execute?
But compiling both of them together gives a multiple declaration error:
$ gcc prog.c static.o static.o: In function `main': static.c:(.text+0x0): multiple definition of `main' /tmp/ccrFqgkh.o:prog.c:(.text+0x0): first defined here collect2: ld returned 1 exit status
Can anyone please explain this behavior?
it's not possible in c to have more than 1 main-function. you could use preprocessor directives like "#ifdef" to compile just one main-function at the time.
There are two types of function in C programming: Standard library functions. User-defined functions.
We can't have more than one main() function in a project. Hint: Function can return only one value.
The reason is that main is called twice: Explicitly, from the static initialization block as soon as the class is loaded. Implicitly, on program entry as soon as the program starts.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With