2013-10-21 2 views
3

https://stackoverflow.com/a/6614369/1091587에는 "gcc3"-type name을 사용하여 컴파일 된 프로그램의 기호 테이블을 읽을 때 나타나는 소멸자 유형 (D0, D1, D2)의 빠른 요약이 있습니다. mangling. 또한 해당 생성자 C0/C1/C2도 있습니다. g ++ - 4.7 (이전 버전 일 수도 있음)에서는 새로운 ctor/dtor 쌍, 즉 C5/D5가 나타나지만 디버깅 기호로만 나타납니다.gcc name mangling의 "destructor group"기호는 무엇입니까

$ cat i.cpp 
class X { public: virtual ~X() {}; }; 
int main(void) { X x; return 0; }; 
$ g++ -c i.cpp 
$ nm i.o | grep 5 
0000000000000000 n _ZN1XC5Ev 
0000000000000000 n _ZN1XD5Ev 
$ c++filt -n _ZN1XC5Ev _ZN1XD5Ev 
X::X() 
X::~X() 

demangler 소스는 D5는 "gnu_v3_object_dtor_group을"개체 호출하지만 정확히 dtor 그룹은 무엇이며, 그것이 좋은 무엇인가? clang ++ - 3.3은 그것을 방출하지 않으며 http://gcc.gnu.org/ml/gcc-patches/2011-11/msg00383.html은 gcc의 새로운 트랜잭션 메모리 기능과 관련이있을 것이라고 제안합니다.

답변

2

This LLVM patchthis GCC bug은 더 많은 배경을 제공합니다. 생성자와 소멸자 의

두 (때로는 세) 동일한 사본이 규정되어있는 링크를 따라 나는 그것의 근원이 될 것으로 보인다 Bug 3187 - gcc lays down two copies of constructors을 발견했다. 링커에서는이 오류가 발생하지 않지만 으로 생성 된 바이너리는 실제보다 20 % 더 커집니다.

"PR C++/3187"(e.g.)을 검색하면 gcc-patches ML에 대한 많은 토론을 찾을 수 있습니다. 기본적으로 C5/D5는 자체적으로 생성자/소멸자가 아니라 두 개 이상의 "기본"생성자/소멸자가 포함 된 COMDAT group입니다. 이렇게하면 그룹의 함수가 모두 최종 바이너리에서 사용되거나 모두 폐기됩니다 ("하나의 정의 규칙"을 적용하기 위해). 구현이 생성자/소멸자 당 하나의 COMDAT를 사용하거나 C5/D5의 COMDAT를 사용할 수있는 옵션이있는 클래스

:

위 버그의 토론의 결과는 다음과 같다. 나는 어떤 수익성 기준에 기초하여 그 결정을 로 할 수 있습니다. C5/D5 comdat 을 사용하는 경우 규칙은

  • 입니다. C5 comdat에는 C1과 C2가 있어야합니다.
  • 클래스에 가상 소멸자가있는 경우 D5 comdat에 D0, D1 및 D2가 있어야합니다.
  • 클래스에 비가 상 소멸자가있는 경우 D5 comdat에 D1 및 D2 소멸자 만 있어야합니다. 즉, 구현 을 구현하는 대신 D1 + _ZdlPv에 대한 호출의 D0를 사용하는 경우에도 마찬가지입니다

당신은 예를 들면하여 comdats을 볼 수 있습니다 "* X 삭제" readelf -G와 파일을 덤프 :

COMDAT group section [ 1] `.group' [_ZN1XD5Ev] contains 2 sections: 
    [Index] Name 
    [ 10] .text._ZN1XD2Ev 
    [ 12] .text._ZN1XD0Ev 

COMDAT group section [ 2] `.group' [_ZN1XC5Ev] contains 1 sections: 
    [Index] Name 
    [ 14] .text._ZN1XC2Ev 

(이는 위의 정의와 일치하지 않는 이유 아마 인 GCC 4.6입니다)