2009-10-23 5 views
6

LLVM은 내장 된 RTTI보다 속도가 향상되고 vtable (dyn_cast)이없는 클래스에 동적으로 캐스팅 할 수 있도록 RTTI의 대안으로 채택되었습니다. 그러나 더 많은 클래스와 함께 사용할 수는 있지만 정확히 dynamic_cast<>이 사용 된 것과 똑같이 사용할 수 있습니다.LLVM은 동적 캐스트를 피하는 규칙에 대한 예외입니까?

dyn_cast<> template documentation

LLVM은 평판 C++ 프로젝트는 그래서이 너무 많은 동적 캐스트는 또한 코드 냄새로 알려진 나쁜 디자인의 상징이라고 말하는 공통의 얼굴에 비행하는 것입니다. 확실히 더 나은 다이나믹 캐스트는 표준 디자인 인 dynamic_cast보다 디자인 용도를 향상시키는 데 아무런 도움이되지 않습니다. 그럼 누가 여기 있니? 다이나믹 캐스팅의 대규모 사용이 C++ 코드에서 좋은 설계 선택 인 경우가 있습니까? Google은 LLVM 트렁크 소스 코드에서 이러한 종류의 동적 캐스팅을 690 번 나타냅니다.

Uses of dyn_cast<> in LLVM trunk

+0

간단히 말해서 "때로는 대규모 소프트웨어 프로젝트에서 규칙 중 일부를 구부리라고해야합니다"라고 생각합니다. 아니면 "컴파일러 또는 컴파일러 관련 프레임 워크가 일반적으로 나쁜 생각 인 저수준의 속임수로 해결해야합니다." 그렇다고해서 일반적인 'dynamic_cast' * 사용에 관해 결론을 내릴 수는 없습니다. * – jalf

+0

이것은'규칙 '을 완전히 무시한 것 같습니다. 나는 규칙을 굽히는 690 사건을 부르지 않을 것이다.필자는 디자인 신념을 깨뜨리는 것이 허용된다는 것을 의미하는 컴파일러 나 컴파일러 관련 프레임 워크에 특별한 것을 보지 못했다. 여기에있는 동적 캐스팅은 컴파일러의 출력 코드 또는 입력 코드에 아무런 영향을 미치지 않습니다. 이는 단순히 디자인의 일부입니다. 필자는 충분히 크거나 복잡한 소프트웨어가 디자인 룰을 무시할 수 있다는 주장을 계속할 수 있습니다.이 규칙은 'dynamic_cast'를 피하기 위해 이런 종류의 디자인 조언에 심각하게 의문을 제기합니다. –

답변

7

대형 히어로 계층에서는 성능 히트가 dynamic_cast<>을 피할 수 있지만 그만큼 피할 수있는 것은 아닙니다. 더 나은 수행 여부,이 주장 때문에 dyn_cast<>을 사용하는 것이 더 이상 권장되지 않습니다.

한편, dynamic_cast<>이 작업에 가장 적합한 도구 일 때는 아무런 문제가 없습니다. 그것의 사용이 정당화되고 문제를 해결하는 가장 깨끗한 방법이라면, "일반적인 말"에 관계없이 항상 옳습니다.

나는 단지 인기가 많은 프로젝트를 명확하게 처리하지 않는다. 왜냐하면 단순히 dynamic_cast<>, goto 또는 그 밖의 다른 관용구를 사용하기 때문이다.

+0

물론 위대한 프로젝트라고 생각합니다. 그렇다면 dynamic_cast <>'를 피하기 위해 조언을 덜주의 깊게 받아 들여야한다는 뜻입니까? –

+0

아니요, 사용하는 경우 조언을 명심해야하며 "이 방법이 가장 좋은 방법입니까?" –

1

나는 그들이 천천히 때문에 다이나믹 캐스트는 나쁘지 않다 생각하지만, 그들은 당신의 코드가 너무 밀접하게 결합되어 있다는 것을 의미하기 때문이다.

+0

그들은 너무 느립니다. 약 1 마이크로 초 우리를 위해 팝업. – Crashworks

+0

@ Crashworks - 상속 계층은 얼마나 깊습니까? 나는 GCC의'dynamic_cast' 구현이 깊이에서 O (n)라고 생각하는데, 이것은 일부 시스템에서는 매우 나쁠 수 있습니다. – Tom

+0

테스트 한 경우 약 6-8 단계라고 생각합니다. 말 그대로 앱 전체에 수천 개의 수업이 있습니다. – Crashworks

-1

저는 LLVM 문서에서 dyn_cast 및 isa의 구현을 살펴 보았습니다.

코드의 exmaple은 다음과 같습니다

테스트는 B로 전화를 가지고있다
struct bar { 
    bar() {} 
private: 
    bar(const bar &); 

}; 
struct foo { 
    void ext() const; 
    /* static bool classof(const bar *X) { 
    cerr << "Classof: " << X << "\n"; 
    return true; 
    }*/ 
}; 

template <> inline bool isa_impl<foo,bar>(const bar &Val) { 
    errs() << "Classof: " << &Val << "\n"; 
    return true; 
} 

:

if (!isa<foo>(B1)) return; 
if (!isa<foo>(B2)) return; 

내가 올바르게 isa 템플릿을 무슨 일이 일어나고 있는지 이해한다면 (이 dyn_cast에 의해 사용됨)은 바를 foo와 링크하기 위해 명시 적 전문화를 isa_impl으로 사용합니다. 주어진 예제에서는 isa<foo>(B1)이 true를 반환합니다!

어쨌든 이것은 dynamic_cast의 동작과 매우 다른 동작이므로 서로 비교할 수 없다고 생각합니다.

분명히, 나는 LLVM이 무엇을하고 있는지 잘못 이해하고있을 수 있으므로 코드를 이해하지 못했다면 알려 주시기 바랍니다!

+0

문서에서 직접 참조 : dyn_cast <> 연산자는 "확인 캐스트"작업입니다. 피연산자가 지정된 유형인지 여부를 확인한 후 피연산자가 지정된 유형인지 확인한 후 피연산자가 포인터를 반환합니다 (이 연산자는 참조에서 작동하지 않음). 피연산자가 올바른 유형이 아닌 경우 널 포인터가 리턴됩니다. 따라서 C++의 dynamic_cast <> 연산자와 매우 유사하게 작동하며 동일한 상황에서 사용해야합니다. 그래서 왜 dynamic_cast와 dyn_cast를 비교할 수 없는지 알지 못합니다. 귀하의 예제에서 나는 B1과 B2가 어디에서 왔는지 알지 못합니다. –

+0

위의 코드는 질문에서 언급 한 페이지의 링크에서 가져온 것입니다. 이것은 그들의 (즉, LLVM의) 코드입니다. 다음은 직접 링크입니다 : http://llvm.org/doxygen/Casting_8h-source.html. B1과 B2는 그 페이지의 아래쪽에있는 예에서 나온 것입니다. 나는 그들의 머리말에서 코드를 자르고 붙였다. BTW, 여기에 붙여 넣은 것은 실제로 동적 인 캐스트가 어떻게 발생 하는지를 말합니다. 그것은 단지 dynamic_cast와 비슷한 "체크 캐스트"라고 말합니다. –

+1

구현이 실제로 내가 묻는 질문에 영향을 미치지 않는다고 생각합니다. 이 문서의 핵심적인 인용문은 '이것은 C++의 dynamic_cast <> 연산자와 매우 유사하게 작동하므로 동일한 상황에서 사용해야합니다.' –

관련 문제