Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Compiling C++ without the delete operator

I am writing a C++ program for an embedded device, and I want to compile it without libstdc++, exceptions, and dynamic memory allocation.

Example program:

#include <stdio.h>

class A
{
public:
    virtual ~A() {}
    virtual void Foo() = 0;
};

class B : public A
{
public:
    virtual ~B() {}
    virtual void Foo() override{}
};

int main()
{
    B b;
    return 0;
}

Immediately I ran into the following errors.

$ gcc src.cpp -static -fno-rtti -fno-exceptions -std=c++11

/tmp/ccd0Wydq.o: In function A::~A()': src.cpp:(.text._ZN1AD2Ev[_ZN1AD5Ev]+0x29): undefined reference to operator delete(void*)' /tmp/ccd0Wydq.o: In function A::~A()': src.cpp:(.text._ZN1AD0Ev[_ZN1AD5Ev]+0x20): undefined reference to operator delete(void*)' /tmp/ccd0Wydq.o: In function B::~B()': src.cpp:(.text._ZN1BD2Ev[_ZN1BD5Ev]+0x35): undefined reference to operator delete(void*)' /tmp/ccd0Wydq.o: In function B::~B()': src.cpp:(.text._ZN1BD0Ev[_ZN1BD5Ev]+0x20): undefined reference to operator delete(void*)' /tmp/ccd0Wydq.o:(.rodata._ZTV1A[_ZTV1A]+0x20): undefined reference to `__cxa_pure_virtual' collect2: error: ld returned 1 exit status Makefile:2: recipe for target 'all' failed make: *** [all] Error 1

I understand why __cxa_pure_virtual is needed, but couldn't for the life of me get why I need a delete implementation.

I perform no new or delete operations in the code, why would it be needed?

When implementing both functions to satisfy the linker's demands, it seems that neither are called (as expected).

Is there a way to avoid implementing these functions?

like image 591
Gilad Naaman Avatar asked Aug 22 '16 16:08

Gilad Naaman


People also ask

When to use delete [] or delete?

delete is used for one single pointer and delete[] is used for deleting an array through a pointer.

What does delete [] mean in C++?

Delete is an operator that is used to destroy array and non-array(pointer) objects which are created by new expression. Delete can be used by either using Delete operator or Delete [ ] operator. New operator is used for dynamic memory allocation which puts variables on heap memory.

What is the difference between delete PTR and delete [] ptr in C ++?

When the delete operator is called, it deallocates memory and calls the destructor for a single object created with new whereas when the delete [] operator is called, it deallocates memory and calls destructors for an array of objects created with new [].

What is the difference between delete and delete in C Plus Plus?

What is the difference between delete and delete[] in C++? Explanation: delete is used to delete a single object initiated using new keyword whereas delete[] is used to delete a group of objects initiated with the new operator.


1 Answers

When a virtual destructor is called via a delete expression, the operator delete that gets called is determined from the scope of the most-derived class. For example,

#include <iostream>

class Base {
public:
    virtual ~Base() {}
};

void destroy_base(Base* b) { delete b; }

class Derived : public Base {
public:
    static void operator delete(void* ptr) {
        std::cout << "Derived::operator delete\n";
        ::operator delete(ptr);
    }
};

int main() {
    destroy_base( new Derived );
}

prints "Derived::operator delete", even though function destroy_base has no knowledge of class Derived.

g++ implements this by putting two versions of the destructor in every class's vtable: one that just destroys the members and bases, and one that does all that and then calls the appropriate operator delete. This is where your undefined symbols are coming from.

If you never actually use a delete expression, just stub out the ::operator delete function and you should be fine.

like image 111
aschepler Avatar answered Sep 22 '22 23:09

aschepler