2009-10-09 7 views
5

는 ++ 난 단지 배열에 대한 읽기 전용 액세스를 필요로하지만, 실수로 const가 아닌 포인터 수신으로 선언하는 기능이 있습니다const 개체에 대한 읽기 전용 액세스를 위해 const_cast를 사용하고 있습니까? 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])); 

이것은 정의되지 않은 동작입니까? 그렇다면 - 프로그램이 UB로 언제 실행됩니까? - const_cast를 수행하고 functon을 호출 할 때 또는 배열에 액세스 할 때?

+0

나는 함수 선언을 변경할 수 없다고 생각하지만, 더 나은 래퍼를 작성하고 더러운 작업을 강력하게 권합니다. –

+0

아마도 다른 일을 시도해보십시오 :'size_t numZeros = std :: count (array, array + sizeof (Array)/sizeof (Array [0]), 0); ' – MP24

+0

@ MP24이 함수는 문제. – sharptooth

답변

13

네, 허용됩니다 (위험하다면!). const 객체에 대한 실제 쓰기는 캐스트 자체 (7.1.5.1/4 [dcl.type.cv])가 아니라 정의되지 않은 동작을 발생시킵니다.

5.2.11/7 [expr.const.cast]의 표준 참고 사항에 따라 객체 형식에 따라 const을 멀리 던진 결과 인 포인터를 통해 쓰려고하면 정의되지 않은 동작이 발생할 수 있습니다.

-2

처음에 const으로 정의 된 개체에 const_cast을 사용하면 정의되지 않은 동작은 const_cast이라고하는 지점에서 즉시 발생합니다.

+3

아니요. UB는 const 객체에 쓰는 순간에 constness를 제거하지 않습니다. –

+0

오, 미안 해요 interwebs에 대한 충고가 있습니다. –

+3

이러한 웹은 까다로울 수 있습니다. – GManNickG

1

코드가 배열을 수정하지 않고 컴파일러에서 const_cast을 사용하여 수행중인 작업을 알았 으면 실제로 문제가되지 않습니다. 그러나, 나는 당신이 기술적으로 정의되지 않은 행동을하고 있다고 믿는다. 함수 선언을 고정 시키거나 const-safe 버전을 작성하고 선언하고 사용하는 것이 가장 좋습니다.

+0

const를 "Effective C++"또는 "More Effective C++"에서 사용하는 방법을 읽어보십시오. const_cast의 일부 유효한 사용법을 보여줍니다 (예 : 일부 코드 중복을 피하기 위해). –

+0

-1 이것은 정의되지 않은 동작이기 때문에 -1; 역사적으로 C++ 98 코드는 사전 표준 C와 상호 운용하기 어려웠을 것입니다. 그러나 조언을 전적으로 전합니다. –

1

네, 그렇게 할 수 있습니다. 아니요, 함수가 실제로 배열에 쓰려고하지 않는 한 정의되지 않은 동작이 아닙니다.

1

const_cast의 문제는 항상 동일합니다. void* (으)로 전송하는 것과 마찬가지로 "규칙을 어기는"것을 허용합니다. 물론 할 수는 있지만 문제는 무엇입니까?

이 경우 물론 괜찮습니다.하지만 왜 처음에 size_t countZeroes(const int* array, size_t count)을 선언하지 않았습니까?

하고

일반적인 규칙에 대한 const_cast :

  1. 그것은 당신이 언어를 전환하고
  2. 기본적으로 컴파일러와 const를-계약을 버리는 것
  3. 버그를 찾기 어려운 생성 할 수 낮은 수준으로 변환합니다.