¿Qué es una "Función clave" de C++ descrita por gold?


Por favor, no responda a la pregunta "¿cómo resuelvo este mensaje de error?"

En el mensaje de error proporcionado por gold:

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

¿Qué es un key function? Encuentro referencia a ella en la página de manual de GCC para Atributos de función en la sección dllimport. El texto pertinente dice:

En el destino SH Symbian OS, el atributo dllimport también tiene otro efecto (sic): puede hacer que se exporten la información de tipo vtable y de tiempo de ejecución de una clase. Esto sucede cuando la clase tiene un constructor dllimport'ed o una función virtual no inline, no pura y, para cualquiera de esas dos condiciones, la clase también tiene un constructor inline o destructor y tiene una función clave que se define en la unidad de traducción actual.

De esto tomo que hay alguna función distinta de los constructores o destructores, requerida bajo algunas condiciones, cuando se usa el atributo dllimport, en el sistema operativo Symbian. Interesante, pero estoy compilando para Linux en Linux, y grep -r dllimport no revela nada. Por lo tanto, este párrafo no se aplica.

(FWIW el problema deriva (en este caso) de un undefined destructor pero tanto la documentación como la salida del enlazador hacen grandes esfuerzos para distinguir una "función clave" de un destructor. Para otros tipos de símbolos que faltan, el enlazador deletrea el nombre del símbolo que falta.)

Entonces, ¿qué es un key function ¿realmente ?

 26
Author: Barmar, 2017-08-24

2 answers

La función Key se define como la primera función virtual no inline declarada en la clase. El wiki oficial de gcc sobre esto es aquí .

 21
Author: navylover,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-08-23 22:25:27

(moviendo/expandiendo desde el comentario)

Como @navylover explicó, la función key es la primera función virtual no en línea definida en la clase; es importante porque es utilizada por el compilador como un marcador convencional para decidir en qué TU debe emitirse la vtable (ya que debe emitirse solo una vez)-cualquiera que TU contenga la definición de la función key, el módulo de objeto correspondiente también contendrá la vtable.

Se deduce que, si no hay una UT define la clave función (por ejemplo, porque se olvidó de definirla), la vtable nunca se emitirá, de ahí el error.

Gold está tratando de indicarte en la dirección correcta: si falta la vtable, probablemente es porque también falta la función key (de nuevo, ya sea porque no definiste u olvidaste vincular su módulo), aunque puede que no aparezca explícitamente como una referencia indefinida (lo que podría ponerte en el camino correcto) porque en el resto del código nadie la invoca directamente1, como en este ejemplo:

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

Compare esto con GNU ld normal, que solo dice

[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, ¿y qué? No es que tenga que definir explícitamente vtables, por lo que definitivamente no es obvio dónde debo empezar a buscar para ir arreglando este tipo de error.


  1. Sin embargo, tal función puede ser invocada indirectamente a través de un puntero a la clase base, y el enlazador todavía mostraría solo la referencia indefinida a la clase base. vtable y no a la función, ya que la única referencia a la función en este caso estaría en la vtable, que falta.
 11
Author: Matteo Italia,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-08-24 00:30:44