2009-07-29 6 views
22

Dans l'exemple suivant, le programme devrait imprimer « foo appelé »:Pourquoi __attribute __ ((constructeur)) ne fonctionne-t-il pas dans une bibliothèque statique?

// foo.c 
#include <stdio.h> 

__attribute__((constructor)) void foo() 
{ 
    printf("foo called\n"); 
} 

// main.c 
int main() 
{ 
    return 0; 
} 

Si le programme est compilé comme celui-ci, cela fonctionne:

gcc -o test main.c foo.c 

Cependant, si foo.c est compilé dans une bibliothèque statique, le programme n'imprime rien.

gcc -c main.c 
gcc -c foo.c 
as rcs foo.a foo.o 
gcc -o test foo.a main.o 

Pourquoi cela se produit-il?

+0

Pourquoi les downvotes? Quelque chose d'incorrect? –

+0

Je ne suis pas sûr (n'était pas moi!) Mais peut-être que quelqu'un vous a dérogé en répondant à votre propre question si rapidement? – DaveR

+1

Hmm, je voulais juste ajouter une référence utile au site pour un problème non évident. La FAQ indique que répondre à sa propre question est une bonne chose (c'est dans la première section en fait). –

Répondre

13

L'éditeur de liens n'inclut pas le code dans foo.a dans le programme final car rien dans main.o n'y fait référence. Si main.c est réécrite comme suit, le programme fonctionnera:

//main.c 

void foo(); 

int main() 
{ 
    void (*f)() = foo; 
    return 0; 
} 

En outre, lors de la compilation avec une bibliothèque statique, l'ordre des arguments à gcc (ou l'éditeur de liens) est importante: la bibliothèque doit venir après les objets qui le référence.

gcc -o test main.o foo.a 
2

Comme il a été dit, les symboles non référencés d'une archive ne fait pas le binaire de sortie, car linker les rejets par défaut.

Pour remplacer ce comportement lors de la liaison avec la bibliothèque statique, --whole-archive/--no-whole-archive options pour l'éditeur de liens peuvent être utilisés, comme ceci:

gcc -c main.c 
gcc -c foo.c 
ar rcs foo.a foo.o 
gcc -o test -Wl,--whole-archive foo.a -Wl,--no-whole-archive main.o 

Cela peut conduire à binaire pléthorique, parce que tous les symboles de foo.a seront inclus par l'éditeur de liens à la sortie, mais parfois il est justifié.

Questions connexes