C ++ 0x에서 nullptr을 삭제하는 것이 여전히 안전합니까?


84

에서 c++03이 널 포인터를 삭제하면 아무 효과가 없습니다 꽤 분명하다. 실제로 다음과 같이 명시 적으로 명시되어 있습니다 §5.3.5/2.

어느 쪽이든 delete 피연산자의 값이 널 포인터이면 연산이 영향을 미치지 않습니다.

그러나, 현재의 초안 에 대한 c++0x이 문장 누락 된 것으로 보인다. 나머지 초안에서는 delete-expression 의 피연산자가 널 포인터 상수가 아닌 경우 어떻게되는지 설명하는 문장 만 찾을 수있었습니다 . 에서 여전히 정의 된 널 포인터를 삭제하고 c++0x있습니까? 그렇다면 어디에 있습니까?

메모:

여전히 잘 정의되어 있음을 시사하는 중요한 상황 증거가 있습니다.

첫째, 두 문장 §5.3.5/2이 있습니다.

첫 번째 대안 (객체 삭제)에서 delete 피연산자의 값은 널 포인터 값일 수 있습니다.

두 번째 대안 (배열 삭제)에서 delete 피연산자의 값은 널 포인터 값이거나 ...

이것들은 피연산자가 null이 될 수 있다고 말하지만 그 자체로는 실제로 어떤 일이 발생하는지 정의하지 않습니다.

둘째,의 의미를 변경하는 delete 0것은 주요 변경 사항이며 표준위원회가 이러한 특정 변경을 수행 할 가능성은 거의 없습니다. 또한 이것이 c++0x초안 의 호환성 부록 (부록 C)에 획기적인 변경이라는 언급이 없습니다 . 그러나 Annex C는 정보 섹션이므로 표준에 대한 해석이 없습니다.

반면에 null 포인터를 삭제해야 효과가 없다는 사실은 추가 런타임 검사를 의미합니다. 많은 코드에서 피연산자는 null이 될 수 없으므로이 런타임 검사는 제로 오버 헤드 원칙과 충돌합니다. 위원회는 언어의 명시된 디자인 목표에 맞게 표준 C ++를 더 많이 가져 오도록 동작을 변경하기로 결정했을 수도 있습니다.

답변:


101

5.3.5 / 7 내용 :

delete-expression의 피연산자 값이 널 포인터 값이 아니면 delete-expression은 할당 해제 함수 (3.7.4.2)를 호출합니다. 그렇지 않으면 할당 해제 함수가 호출 될지 여부가 지정되지 않습니다.

그리고 3.7.4.2/3은 다음과 같이 말합니다.

할당 해제 함수에 제공된 첫 번째 인수의 값은 널 포인터 값일 수 있습니다. 그렇다면 할당 해제 함수가 표준 라이브러리에 제공된 함수이면 호출이 효과가 없습니다.

따라서 표준 할당 해제 함수를 사용하거나 사용자가 제공 한 할당 해제 함수가 널 포인터를 올바르게 처리하는 한 동작이 잘 정의되어 있습니다.


9
C ++ 14 이후 "식이 널 포인터 값으로 평가되면 소멸자가 호출되지 않고 할당 해제 함수가 호출되지 않습니다."
Wormer

2
@Wormer 나는 그 페이지가 정확하다고 생각하지 않습니다. C ++ 14 표준은 포인터가 null (5.3.5 / 7) 일 때 "할당 해제 함수를 호출할지 여부는 지정되지 않았습니다"라고 말합니다.
interjay

1
제쳐두고, null 파일 포인터에 대해 fclose ()를 호출하는 것은 안전 하지 않습니다 . Ubuntu (및 기타 운영 체제)에서 fclose (NULL)는 세그먼트 오류를 ​​일으 킵니다.
Gerry Beauregard

7

반면에 null 포인터를 삭제해야 효과가 없다는 사실은 추가 런타임 검사를 의미합니다.

새로운 문구는 null 포인터에 대한 런타임 검사를 제거하지 않습니다. 다른 방법으로 표준 초안은 구현시 널 포인터 테스트를 준수 해야 한다고 말하는 것에 훨씬 더 가까워집니다 .

또한 주목할만한 점 : 이전 표준은 "삭제 피연산자의 값이 널 포인터이면 연산이 효과가 없다"고 (5.3.5 / 2)라고 말했지만 나중에 (5.3.5 / 7) "delete-expression은 할당 해제 함수를 호출합니다." 함수 호출은 효과입니다. 호출 된 함수가 재정의 될 수 있기 때문에 특히 그렇습니다 operator delete.

새로운 문구는 그 모순을 제거하고 null 포인터를 삭제할 경우 할당 해제 함수가 호출되는지 여부를 구현에 명시 적으로 남겨 둡니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.