On Fri, 2023-03-03 at 12:39 +0000, Nguyen Duc Sy wrote: > As per your explanation, I tried to understand. Whether, in all cases, > if I use a base class to be inherited, does the destructor always > generate two variants (D0 and D2)? Maybe 3 variants. See http://itanium-cxx-abi.github.io/cxx-abi/abi.html#mangling. D0 is the deleting destructor, D1 is the complete object destructor, D2 is the base object destructor. The base object destructor of a class T T runs the destructors for non- static data members of T and non-virtual direct base classes of T. The complete object destructor of a class T in addition to the actions required of a base object destructor, runs the destructors for the virtual base classes of T. The deleting destructor of a class T in addition to the actions required of a complete object destructor, calls the appropriate deallocation function (i.e,. operator delete) for T. > But when I change the code as below: > virtual ~Base(){ > cout << "Base Destructor called\n"; > } > to > ~Base(){ > cout << "Base Destructor called\n"; > } > the D0 destructor variant doesn't generate. "A function defined within a class definition is an inline function." And, "an inline function or variable shall be defined in every translation unit in which it is odr-used and shall have exactly the same definition in every case" [dcl.inline]. So the compiler can avoid generating the destructor as it's not used in the current TU. If it's used in another TU, a valid definition will be in that TU anyway. But when you make it virtual, the compiler need to fill the address of the destructor into the vtable: _ZTV4Base: .quad 0 .quad _ZTI4Base .quad _ZN4BaseD1Ev .quad _ZN4BaseD0Ev So the compiler generates the code for the destructor in all TUs as it *might* be used through vtable from another TU. However, as Base itself does not have a base class, I can't figure out a valid way to invoke it through the vtable without including the definition of the destructor in the TU. So it seems valid to avoid generating the code for _ZN4BaseD0Ev unless it's used in the TU. Note that it's a weak symbol so we can rely on the linker to fill 0 into vtable if it's not use at all. But maybe I'm missing something here (I'm not a language lawyer). Anyway, AFAIK the compilers tend to ignore "inline" in "inline virtual" functions. -- Xi Ruoyao <xry111@xxxxxxxxxxx> School of Aerospace Science and Technology, Xidian University