traduccion meaning installed berserk c++ clang

c++ - meaning - ¿Cuál es el significado de clang''s-Wweak-vtables?



llvm 3.7 0 (1)

Básicamente no entiendo clang''s -Wweak-vtables . Esto es lo que observé hasta ahora:

Caso uno: (activa la advertencia)

class A { public: virtual ~A(){} }; class B : public A { public: virtual ~B(){} }; int main(){}

Caso dos: (No activa la advertencia)

class A { public: virtual ~A(){} }; int main(){}

Caso tres: (No activa la advertencia)

class A { public: virtual ~A(); }; A::~A(){} class B : public A { public: virtual ~B(){} }; int main(){}

Caso cuatro: (Advertencia de activadores)

class A { public: virtual ~A(){} virtual void fun(){} }; class B : public A { public: virtual ~B(){} }; int main(){}

Caso cinco: (No activa la advertencia)

class A { public: virtual ~A(){} virtual void fun(); }; class B : public A { public: virtual ~B(){} }; int main(){}

Caso seis: (No activa la advertencia)

class A { public: virtual ~A(){} virtual void fun(){} }; class B : public A {}; int main(){}

Caso siete: (No activa la advertencia)

class A { public: virtual ~A(){} virtual void fun(){} }; class B : public A { public: virtual void fun(){} }; int main(){}

La advertencia exacta es

warning: ''A'' has no out-of-line virtual method definitions; its vtable will be emitted in every translation unit [-Wweak-vtables]

Así que aparentemente, si no declaro una función virtual no en línea en una clase, causa algún tipo de problema si y solo si derivo de ella y la clase derivada tiene un destructor virtual.

Preguntas:

  1. ¿Por qué es esto un problema?
  2. ¿Por qué esto se arregla declarando una función virtual? (La advertencia habla de definiciones)
  3. ¿Por qué la advertencia no se produce cuando no procedo de la clase?
  4. ¿Por qué la advertencia no se produce cuando la clase derivada no tiene un destructor virtual?

Si todos virtual métodos virtual de una clase están en línea, el compilador no tiene manera de seleccionar una unidad de traducción en la que colocar una única copia compartida de la tabla. En su lugar, se debe colocar una copia de la tabla en cada archivo objeto que la necesite. . En muchas plataformas, el enlazador puede unificar estas copias múltiples, ya sea descartando definiciones duplicadas o asignando todas las referencias a una copia, por lo que esto es solo una advertencia.

La implementación de una función virtual fuera de línea permite al compilador seleccionar la unidad de traducción que implementa ese método fuera de línea como "hogar" para los detalles de implementación de la clase, y coloca la única copia compartida de vtable en la misma traducción unidad. Si hay varios métodos fuera de línea, el compilador puede hacer una elección arbitraria siempre y cuando esa elección esté determinada únicamente por la declaración de la clase; por ejemplo, GCC elige el primer método no en línea en el orden de declaración.

Si no anula ningún método de una clase, la palabra clave virtual no tiene un efecto observable, por lo que no es necesario que el compilador emita un vtable para la clase. Si no se deriva de A , o si no se declara el destructor virtual una clase derivada, no hay métodos anulados en A y, por lo tanto, se omite vtable de A Si declara un método virtual fuera de línea adicional para suprimir la advertencia y también hace algo que invalida un método en A , la implementación del virtual no en línea (y la copia que lo acompaña de la plataforma) debe suministrarse en una unidad de traducción vinculada, de lo contrario el enlace fallará porque falta la vtable.