2014-09-08 6 views
57

나는 오래된 프로젝트의 몇과 같은 코드를 본 적이 : 그것은 (상관없이 나중에 무슨 일) 널 포인터를 역 참조하지 포함되어 있기 때문에코드가 null 포인터를 통해 정적 메서드를 명시 적으로 호출하는 이유는 무엇입니까?

class Class { 
    static void Method() {} 
}; 

((Class*)0)->Method(); 

이 코드는 정의되지 않은 동작이 포함되어 있습니다. 정말 말도 안돼 - 캐스트가 컴파일러와 누구든지 위의이 대신 작성한 수있는 코드 작성에 유형 이름을 공급하는이 :

Class::Method(); 

후자는 괜찮을 것입니다.

왜 이전 코드를 작성합니까? 옛 시절의 유명한 관용구인가요?

+0

그리고 여기서는 인스턴스 참조를 통해 클래스 멤버를 호출 할 수있는 자바라고 생각했습니다. 허. –

+0

또 다른 흥미로운 비슷한 점이 있습니다. 메소드가 정적이 아니더라도 'this'를 사용하지 않거나 클래스의 필드를 사용하면 IllegalAccess 오류가 발생하지 않습니다. 이 (가)'class C {void f() {cout << "something"; }} C * instance = nullptr; instance-> f(); ' –

+0

이 코드에 의해 null 포인터가 _dereferenced_ 될 것이라고 생각합니까? 왜 x-> staticMethod()는 x를 참조 해제합니까? – gnasher729

답변

67

정적 멤버 함수는 AT & T C++ 언어 시스템 (사전 표준화)의 Release 2.0에 C++에 추가되었습니다. 그 전에는 static 키워드를 사용하여 정적 멤버 함수를 선언 할 수 없었으므로 코드 작성자는 주로 사용자가 간접적으로 널 포인터를 사용하는 것을 보았던 해결 방법을 사용했습니다. 섹션 1-22에서 AT & T C++ 언어 시스템의 버전 ​​2.0과 함께 제공되는 Selected Readings에서

은 스트로브 스트 룹의 글 :

은 또한 관찰 그와 같은 이식성 코드 :

((X*)0)->f(); 

은 정적 멤버 함수를 시뮬레이트하는 데 사용되었습니다. 이 트릭은 조만간 누군가가 f()을 사용하여이 방법으로 virtual을 사용하게되며 어드레스 0에 X 오브젝트가 없기 때문에 통화가 끔찍하게 실패 할 것이기 때문에 시한 폭탄입니다. 심지어 f()이 가상 링크가 아닌 경우에도 동적 연결의 일부 구현에서는 이러한 호출이 실패합니다.

코드가 Cfront 1.0 또는 언어에 정적 멤버 함수 추가시 인식하지 못하는 사람이 컴파일하도록 작성되었습니다.

static이있는 멤버 함수의 주석은 참으로 퍼즐입니다. 건배와 hth. - Alf이 관찰되었습니다. Cfront 1.0은 그 코드를 다음과 같이 거부했습니다 :

error: member Method() cannot be static 

그래서 처음에는 거기에있을 수 없었습니다. 나는 Potatoswatter가 일 가능성이 가장 높다고 생각합니다. static은 추후에 추가되어 C++ 2.0 컴파일러가 사용 가능하게 보장되지만 호출 코드가 업데이트되지 않으면 정적 메서드 속성 Method을 문서화하고 적용합니다. 이것을 확인하려면 원본 프로그래머와 인터뷰하거나 소스 제어 내역 (있는 경우)을 검사해야합니다.

+6

+1 나는 90 년대의 플래시백을 좋아한다. – LihO

+0

Stroustrup은 왜 정의되지 않은 행동의 더 심각한 문제에 대해 언급하지 않는가? 구현 세부 사항을 가지고 논쟁한다. – usr

+1

@usr 실제 충돌 *은 정의되지 않은 행동 때문이다. *나는 n 이론. – Potatoswatter