2014-05-20 6 views
3

부스트/any.hpp (버전 1.55) (라인 263) 원래 객체 boost :: any_cast (const any)는 const_cast <>를 사용합니다 - 잠재적으로 UB가 아닌가요?

같이 const 선언되지 않은 경우에 정의되지 않은 동작 될 수 const_cast<>, 를 사용하지만

template<typename ValueType> 
inline const ValueType * any_cast(const any * operand) BOOST_NOEXCEPT 
{ 
    return any_cast<ValueType>(const_cast<any *>(operand)); 
} 

를 정의

class foo 
{ 
    boost::any value; 
    template<typename T> 
    foo(T const&x) noexcept : value(x) {} 

    template<typename T> 
    const T*ptr() const noexcept 
    { return boost::any_cast(value); } 
}; 

그럼 부자가 되겠습니까?

+0

당신이 잘못 인용하지 않았습니까? UB 원래 const가 아닌 obj에서 const를 제거하면 어떻게됩니까? – sp2danny

+1

함수가 const가 아닌 값 유형에 대한 포인터를 반환하면 UB *로 이어질 수 있지만 그렇지 않습니다. 상수, 상수. 함수 내부의 코드? 그것은 단지 캐스팅이고 객체를 수정하지 않습니다. –

+0

흠. 나는 오래된 기준에 의해 잘못 인도되었을지도 모른다. 그래서'const_cast <> (non_const_object)'는 UB가 아닙니다. – Walter

답변

4

any_cast이 포인터를받는 const 포인터와 any_cast을 반환하기 때문에 합법적 인 코드입니다. 인수를 변경하지 않습니다.

n3376 5.2.11/7

[참고 : 객체, 쓰기 작업의 종류에 따라 을 통해 당신이 const_cast를 사용하는 경우 표준으로

UB는 1 상황에서 할 수 있습니다 포인터, 왼쪽 값 또는 const 한정자를 멀리 던지는 const_cast에서 발생하는 데이터 멤버에 대한 포인터는 정의되지 않은 동작 (7.1.6.1)을 생성 할 수 있습니다. - 어쩌면 당신은 [expr.const.cast]#7 생각하고 엔드 노트]

3

:

[참고

을 : 개체의 유형에 따라 데이터 멤버에 대한 포인터, 좌변 또는 포인터를 통해 쓰기 작업이 결과 const-qualifier 73을 제거한 const_cast에서 정의되지 않은 동작 (7.1.6.1)이 발생할 수 있습니다. -end 노트]

섹션 7.1.6.1은 다음과 같습니다

를 제외한 모든 클래스 멤버는 선언 된 것을 변경할 수 (7.1.1)을 수정할 수 있습니다, 수명 동안 const를 개체를 수정하려는 시도 (3.8) 정의되지 않은 동작이 발생합니다.

그러나이 코드에는 이러한 쓰기 작업이 없습니다. [expr.const.cast] 섹션의 나머지 부분에는이 코드에 문제가 있음을 나타내는 내용이 없습니다.