简体   繁体   中英

Does compiler really enforce implementation of pure virtual destructor?

To validate the statement " compiler & linker enforce existence of function body for pure virtual destructor. " from this geeksforgeeks article , I compiled this code:

class Base
{
public:
    virtual ~Base()=0; // Pure virtual destructor
};

class Derived : public Base
{
public:
    ~Derived()
    {
        std::cout << "~Derived() is executed";
    }
};

int main()
{
    //Derived d;   <<<
    return 0;
}

which compiled without any error. So why the compiler didn't chose to enforce the existence of the function body in this case?

Because the compiler (the entire translation process, actually) doesn't have to enforce anything if you perform an ODR 1 violation. According to the C++ standard at [basic.def.odr/4] :

Every program shall contain exactly one definition of every non-inline function or variable that is odr-used in that program; no diagnostic required . The definition can appear explicitly in the program, it can be found in the standard or a user-defined library, or (when appropriate) it is implicitly defined (see [class.ctor], [class.dtor] and [class.copy]). An inline function shall be defined in every translation unit in which it is odr-used.

The compiler is perfectly within its right to figure out your program isn't actually using 2 the destructor of Derived (and therefore the destructor of Base ), and just not bother with notifying you.


1 O ne D efinition R ule
2 What does it mean to “ODR-use” something?

Does compiler really enforce the implementation of the pure virtual destructor?

No the compiler does nothing like this.

The compiler compiles compilation units to object files, that's why it

compiled without any error.

I think nearly every compiler will compile this without any error. But the linker will complain. The compiler just adds code to object files, and also in- and outgoing references that are bound by the linker (for static linking).

Of course the program will not link if you comment-in the line Derived d; again, see online demo .

Update

What you show in your question is just a single compilation unit, if you link it as a program, the linker will probably remove unused code. StorryTeller's answer says a lot about this.

If you comment-in the Derived usage in main and copy the definition of Base class into another compilation unit and add the destructor implementation there, you'll see that both will be linked together and the resulting program will run without any error. The compiler itself doesn't care if you include definitions from headers or not. I don't suggest to do this for productive programming but to understand why the compiler traditionally doesn't care about completeness of definitions. Most real-world compilation units are often incomplete.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM