What is the meaning of clang -weweak-vtables?

Basically I don't understand clang -Wweak-vtables . Here is what I have observed so far:

Case one: (triggers a warning)

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

Case two: (does not raise a warning)

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

Case Three: (does not raise a warning)

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

Case Four: (trigger warning)

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

Case five: (does not raise a warning)

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

Case six: (does not raise a warning)

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

Case seven: (does not raise a warning)

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

Accurate warning

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

Thus, it is obvious that if I do not declare a non-built-in virtual function in the class, this causes some kind of problem if and only if I get it, and the derived class has a virtual destructor.

Questions:

  • Why is this a problem?
  • Why is this fixed by declaring a virtual function? (A warning speaks of a definition)
  • Why does the warning not occur if I do not receive from the class?
  • Why does the warning not occur when the derived class does not have a virtual destructor?
+42
c ++ clang
May 19 '14 at 20:48
source share
1 answer

If all methods of the virtual class are built-in, the compiler cannot select a translation node in which one shared copy of vtable will be placed - instead, a copy of vtable should be placed in each file of the object that needs it. On many platforms, the linker can combine these multiple copies either by discarding duplicate definitions or by matching all references to one copy, so this is only a warning.

Implementation of the virtual out-of-line function allows the compiler to select a translation module that implements this method off-line as β€œhome” for the implementation details of the class, and places one shared copy of vtable in the same translation unit. If several methods are out of turn, an arbitrary choice of method can be made by the compiler if this choice is determined only by the declaration of the class; for example, GCC selects the first non-built-in method in declaration order.

If you do not override any class method, the virtual keyword has no observable effect, so the compiler should not allocate vtable for the class. If you do not come from A , or if you were unable to declare a destructor for the derived class virtual , there are no overridden methods in A , and therefore A vtable is omitted. If you declare an additional out-of-line virtual method to suppress the warning, and also do something that overrides the method in A , the implementation of the non-built-in virtual (and the accompanying copy of vtable) must be put in the associated translation unit, otherwise the connection will not complete because vtable is missing.

+61
May 20 '14 at
source share



All Articles