2016-08-22 6 views
10

임베디드 장치 용 C++ 프로그램을 작성하고 libstdC++, 예외 및 동적 메모리 할당없이 컴파일하려고합니다.삭제 연산자없이 C++ 컴파일

예제 프로그램 :

#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; 
} 

즉시 나는 다음과 같은 오류 다 퉜다. __cxa_pure_virtual가 필요한 이유

$ 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

은 이해하지만, 나는 delete 구현이 필요한 이유 내 인생에 얻을 수 없었기 때문.

코드에서 new 또는 delete 연산을 수행하지 않습니다. 왜 필요합니까?

링커의 요구 사항을 충족시키기 위해 두 가지 기능을 모두 구현할 경우 어느 쪽도 호출되지 않은 것으로 보입니다 (예상대로).

이러한 기능을 구현하지 않는 방법이 있습니까?

+0

아무 것도하지 않아도 구현하는 데 문제가 있습니까? –

+0

나는 큰 assert (1 == 0)로 그들을 스텁 (stub)하여 그들이 호출되지 않았 음을 확신 할 것이다. –

+0

추한 솔루션입니다. 유일한 해결책이라면 해보 겠지만, 왜 그런지 알고 싶습니다. –

답변

12

delete 식을 통해 가상 소멸자가 호출되면 operator delete은 가장 파생 된 클래스의 범위에서 결정됩니다. 예를 들어,

#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); 
} 

인쇄 "Derived::operator delete", 기능 destroy_base 클래스 Derived에 대한 지식이 없다하더라도.

g ++은 모든 클래스의 vtable에 두 가지 버전의 소멸자를 넣음으로써이를 구현합니다. 즉, 멤버와베이스를 파괴하는 것, 그리고 모든 것을 처리 한 다음 operator delete을 호출하는 것입니다. 이것은 정의되지 않은 기호가 나오는 곳입니다.

delete 표현을 실제로 사용하지 않는 경우 ::operator delete 함수를 스텁하기 만하면됩니다.

+0

컴파일러가 두 번째 소멸자를 생성하지 못하게하는 방법이 있습니까? 삭제 연산자를 스터 빙하는 데 관심이 없습니다. –

+0

나는 그렇게 생각하지 않는다. – aschepler

+1

@GiladNaaman, 어떻게 가능할 지 상상할 수 없습니다. 표준에서는 적절한 삭제가 필요하며 기본 클래스를 컴파일 할 때 컴파일러는 사용 방법을 모릅니다. 따라서 연산자 삭제를 호출하는 소멸자를 생성해야합니다. – SergeyA