허용 된 Const 객체에 대한 읽기 전용 액세스를 위해 Const_cast를 사용하고 있습니까?
-
20-09-2019 - |
문제
C ++에서는 배열에 대한 읽기 전용 액세스 만 필요하지만 실수로 잘못된 포인터를받는 것으로 선언 된 기능이 있습니다.
size_t countZeroes( int* array, size_t count )
{
size_t result = 0;
for( size_t i = 0; i < count; i++ ) {
if( array[i] == 0 ) {
++result;
}
}
return result;
}
그리고 Const 배열을 위해 호출해야합니다.
static const int Array[] = { 10, 20, 0, 2};
countZeroes( const_cast<int*>( Array ), sizeof( Array ) / sizeof( Array[0] ) );
이것이 정의되지 않은 행동일까요? 그렇다면 - Const_cast를 수행하고 Functon을 호출 할 때 또는 배열에 액세스 할 때 언제 UB로 연결됩니까?
해결책
예, 허용됩니다 (위험하다면!). 그것은 실제 글입니다 const
캐스트 자체가 아닌 정의되지 않은 동작을 초래하는 객체 (7.1.5.1/4 [dcl.type.cv]).
객체의 유형에 따라 5.2.11/7 [expr.const.cast]의 표준 참고 사항으로 캐스팅의 결과 인 포인터를 통해 쓰려는 시도 const
정의되지 않은 행동을 일으킬 수 있습니다.
다른 팁
코드가 배열을 수정하지 않으므로 컴파일러에 사용하여 사용하여 무엇을하고 있는지 알고 있습니다. const_cast
, 당신은 실제로 괜찮을 것입니다. 그러나 나는 당신이 기술적으로 정의되지 않은 행동을 불러 일으키고 있다고 생각합니다. 함수 선언을 고정하거나 쓰기, 신고 및 사용하는 것이 가장 좋습니다.
예, 그렇게 할 수 있습니다. 아니요, 기능이 어레이에 글을 쓰려고하지 않는 한 정의되지 않은 동작이 아닙니다.
의 문제 const_cast
항상 동일합니다. void*
- 물론 그렇게 할 수 있지만 질문은 왜해야합니까?
이 경우 물론 괜찮지 만 왜 선언하지 않았는지 스스로에게 물어봐야합니다. size_t countZeroes( const int* array, size_t count )
처음에?
그리고 일반적인 규칙으로 const_cast
:
- 버그를 찾기가 어려울 수 있습니다
- 당신은 컴파일러와 함께 const-begreement를 버리고 있습니다
- 기본적으로 당신은 언어를 하위 수준의 언어로 전환합니다.
사용 const_cast
처음에 정의 된 객체에서 const
UB입니까, 따라서 정의되지 않은 행동은 당신이 부르는 시점에서 즉시옵니다. const_cast
.