Oggi, mentre lavoravo con una libreria personalizzata, ho trovato uno strano comportamento. Un codice di libreria statico conteneva una funzione di debug main()
. Non era all'interno di un flag #define
. Quindi è presente anche in biblioteca. E viene utilizzato il collegamento a un altro programma che conteneva il vero main()
.
Quando entrambi sono collegati insieme, il linker non ha generato un errore di dichiarazione multipla per main()
. Mi stavo chiedendo come potrebbe accadere.Come viene compilato ed eseguito questo programma C con due funzioni principali?
Per rendere più semplice, ho creato un programma di esempio, che simula lo stesso comportamento:
$ 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
Come funziona il "2main" find binario che main
per eseguire?
Ma la compilazione e due insieme dà un errore di dichiarazione multipla:
$ 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
Qualcuno può spiegare questo comportamento?
Se si esegue 'nm' nella libreria statica che contiene il primo' main', mostra che il simbolo 'main' è definito (presente e non con un' U' accanto ad esso)? – anol
il collegamento dinamico cerca solo i simboli necessari e rilascia il principale in libstatic.a – tristan
Altri hanno le risposte, ma vorrei commentare che il codice che stai compilando è in violazione della "One Definition Rule" (ODR), che significa comportamento non definito. Capita semplicemente di vedere che aspetto ha questo comportamento indefinito per un compilatore. –