32 votes

Qu'est-ce qu'une "fonction clé" C++ telle que décrite par Gold ?

Ne répondez pas à la question "comment résoudre ce message d'erreur ?".

Dans le message d'erreur fourni par gold :

/usr/bin/ld.gold: the vtable symbol may be undefined
because the class is missing its key function

Qu'est-ce qu'un key function ? Je trouve une référence à ce sujet dans le Page de manuel GCC pour les attributs de fonction en vertu de l'article dllimport . Le texte pertinent est le suivant :

Sur la cible SH Symbian OS, l'attribut dllimport a également un autre effet (sic) - il peut entraîner l'exportation des informations de type vtable et run-time d'une classe. Cela se produit lorsque la classe possède un constructeur dllimporté ou une fonction virtuelle non inline et non pure et que, pour l'une ou l'autre de ces deux conditions, la classe possède également un constructeur ou un destructeur inline et une fonction clé définie dans l'unité de traduction actuelle.

J'en déduis qu'il existe une fonction distincte des constructeurs ou des destructeurs, requise dans certaines conditions, lors de l'utilisation de l'outil de gestion de l'environnement. dllimport attribut, sur Symbian OS. Intéressant, mais je compile pour Linux sur Linux, et grep -r dllimport ne révèle rien. Ce paragraphe ne s'applique donc pas.

(Pour information, le problème provient (dans ce cas) d'un fichier non défini destructeur mais la documentation et le résultat de l'éditeur de liens se donnent beaucoup de mal pour distinguer une "fonction clé" d'un destructeur. Pour les autres types de symboles manquants, le linker épelle le nom du symbole manquant).

Alors, qu'est-ce qu'un key function vraiment ?

27voto

navylover Points 3660

La fonction clé est définie comme la première fonction virtuelle non en ligne déclarée dans la classe. Le wiki officiel de gcc à ce sujet est ici .

17voto

Matteo Italia Points 53117

(déplacement/expansion à partir du commentaire)

Comme l'a expliqué @navylover, la fonction clé est la première fonction virtuelle non inline définie dans la classe ; elle est importante car elle est utilisée par le compilateur comme un marqueur conventionnel pour décider dans quelle UT la vtable doit être émise (car elle ne doit être émise qu'une seule fois) - quelle que soit l'UT contenant la définition de la fonction clé, le module objet correspondant contiendra également la vtable.

Il s'ensuit que, si aucune TU ne définit la fonction clé (par exemple parce que vous avez oublié de la définir), la vtable ne sera jamais émise, d'où l'erreur.

L'or essaie de vous indiquer la bonne direction : si la vtable est manquante, c'est probablement parce que la fonction clé est manquante aussi (encore une fois, soit parce que vous n'avez pas défini ou oublié de lier son module), bien qu'elle puisse ne pas être listée explicitement comme une référence non définie (ce qui pourrait vous mettre sur la bonne voie) parce que dans le reste du code personne ne l'invoque directement. 1 comme dans cet exemple :

struct Test {
    virtual void foo();
    virtual int bar() {
        return 0;
    }
};

int main() {
    Test t;
    t.bar();
    return 0;
}

[matteo@teolapkubuntu /tmp]$ g++ -fuse-ld=gold keyf.cpp 
/tmp/ccduMsT3.o:keyf.cpp:function main: error: undefined reference to 'vtable for Test'
/usr/bin/ld.gold: the vtable symbol may be undefined because the class is missing its key function

Comparez cela avec le GNU ld normal, qui dit simplement

[matteo@teolapkubuntu /tmp]$ g++ keyf.cpp 
/tmp/ccUr3Xyi.o: In function `main':
keyf.cpp:(.text+0x1a): undefined reference to `vtable for Test'
collect2: error: ld returned 1 exit status

Ok, et alors ? Ce n'est pas comme si je devais définir explicitement vtables, donc ce n'est certainement pas évident de savoir où je dois commencer à chercher pour corriger ce genre d'erreur.


  1. Une telle fonction peut toutefois être invoquée indirectement par le biais d'un pointeur vers la classe de base, et le linker ne montrerait toujours que la référence indéfinie à la vtable et non à la fonction, car la seule référence à la fonction dans ce cas serait dans la vtable, qui est manquante.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X