삭제되지 않은 객체에 대해 소멸자가 호출되는 이유는 무엇입니까?
struct A
{
~A() = delete;
};
int main()
{
new A{};
}
다음 오류 메시지와 함께 컴파일되지 않습니다.
오류 : 삭제 된 함수 'A :: ~ A ()'사용 new A {};
내가 이해했듯이 객체를 파괴하지 않고 왜 소멸자를 호출하려고합니까?
GCC 8.1.0으로 컴파일 됨
g++ -std=c++17 -O2
이것은 gcc 버그 57082 입니다.
아래에서 위로 가자.
삭제 된 함수를 선언하는 것 외에 암시 적으로 또는 명시 적으로 참조하는 프로그램의 형식이 잘못되었습니다.
분명히 우리는 ~A()
명시 적으로 언급하지 않습니다 . 암시 적으로 언급하고 있습니까? [class.dtor] / 12 :
소멸자가 암시 적으로 호출 됨
- 프로그램 종료시 ([basic.start.term]) 정적 저장 기간 ([basic.stc.static])으로 구성된 객체의 경우,
- 스레드 종료시 스레드 저장 기간 ([basic.stc.thread])으로 구성된 객체의 경우
- 객체가 생성 된 블록 ([stmt.dcl])이 종료 될 때 자동 저장 기간 ([basic.stc.auto])으로 구성된 객체의 경우,
- 생성 된 임시 객체의 수명이 끝날 때 ([conv.rval], [class.temporary]).
또는 [expr.new] / 20 :
는 IF 새로운 표현은 클래스 타입의 오브젝트의 배열을 생성 소멸자 잠재적 호출된다.
그런 것들이 있습니까? 아니요, 여기에는 자동, 정적 또는 스레드 저장 기간이있는 개체가 없으며 구성된 임시 개체도없고 배열을 만드는 new-expression 도 없습니다 . 여기에는 A
집계 초기화중인 동적 저장 기간이 있는 개체가 하나뿐입니다 .
우리는 명시 적으로도 암시 적으로도 언급하지 않았기 때문에 우리는 ~A()
그 규칙을 넘어 설 수 없습니다. 따라서 gcc 버그입니다. gcc는 이 규칙에 관한 한 동일한 의미를 갖는 new A;
and를 허용 new A();
합니다.
아마도 여기에 gcc 버그 일 것입니다.
표준은 새 표현식이 배열 [expr.new]를 만들 때 소멸자가 잠재적으로 호출되도록 지정합니다 .
new-expression이 클래스 유형의 개체 또는 개체 배열을 만드는 경우 할당 함수, 할당 해제 함수 및 생성자에 대한 액세스 및 모호성 제어가 수행됩니다. new-expression이 클래스 유형의 객체 배열을 생성하면 소멸자가 잠재적으로 호출됩니다.
내 강조
gcc는 비 배열을 생성 할 때도이 규칙을 적용하며 이는 암시 적으로 표준 규칙이 아닙니다. 아래의 주석 덕분에 gcc는 정반대의 작업을 수행하는 것 같습니다. 비 배열을 만들 때 소멸자가 잠재적으로 호출 된 것으로 간주하고 배열을 만들 때 소멸자를 확인하지 않습니다.
내가 알 수있는 한, 예제에서는 어떤 객체도 파괴되지 않으며 표현식이 다음과 같이 변경되면 컴파일됩니다. new A;
컴파일되지 않은 예제 코드는 GCC의 버그라고 생각합니다. Clang은 잘 컴파일합니다 .
새로 추가 된 언어 변호사 태그에 대한 답변입니다.
중요한 표준 규칙은 [class.dtor]에 있습니다.
소멸자가 암시 적으로 호출 됨
... 동적 이외의 다른 저장 기간과 관련하여 적용되지 않는 경우 ...
... 소멸자는 new-expression (5.3.4)에 의해 할당 된 생성 된 객체에 대해 delete-expression (5.3.5)을 사용하여 암시 적으로 호출됩니다. 호출 컨텍스트는 delete-expression입니다. [참고 : 클래스 유형의 배열에는 각각 소멸자가 호출되는 여러 하위 객체가 포함됩니다. — end note] 소멸자를 명시 적으로 호출 할 수도 있습니다. 소멸자는 호출되거나 5.3.4, 12.6.2 및 15.1에 지정된대로 호출 될 수 있습니다.
5.3.4는 [expr.new]로
... new-expression이 클래스 유형의 객체 배열을 생성하면 소멸자가 잠재적으로 호출됩니다 (12.4).
적용되지 않습니다.
12.6.2는 [class.base.init]이며
비 위임 생성자에서 클래스 유형의 잠재적으로 생성 된 각 하위 객체에 대한 소멸자가 잠재적으로 호출됩니다 (12.4).
적용되지 않는
15.1은 [except.throw]로 예외 객체가 소멸되는 방법을 지정하며 적용되지 않습니다.
결론 : 섹션 5.3.4, 12.6.2 및 15.1 없음. 이 경우에 적용되는 규칙을 포함하고 소멸자가 호출되지 않으며 delete-expression도 없습니다. 따라서 소멸자는 잠재적으로 호출되지 않으므로 소멸자를 삭제할 수 있도록 잘 구성되어 있습니다.
'UFO ET IT' 카테고리의 다른 글
MsTest ClassInitialize 및 상속 (0) | 2020.12.09 |
---|---|
Google Code Prettify를 호스팅하는 CDN (Content Delivery Network)이 있습니까? (0) | 2020.12.09 |
MySQL이 집계 함수없이 "그룹 별"쿼리를 허용하는 이유는 무엇입니까? (0) | 2020.12.09 |
merge..output을 사용하여 source.id와 target.id 간의 매핑 가져 오기 (0) | 2020.12.09 |
WebGL 및 ThreeJS의 개선 된 영역 조명 (0) | 2020.12.09 |