const_cast는 안전한가요? 찾을 수있는 유일한

에 대한 정보를 많이 찾을 수 없습니다 const_cast. 내가 찾을 수있는 유일한 정보 (Stack Overflow에서)는 다음과 같습니다.

const_cast<>()/ 변수 제거 CONST (호) (휘발성 또는 호)를 추가하는 데 사용된다.

이것은 나를 긴장하게 만든다. const_cast예기치 않은 동작을 유발할 수 있습니까? 그렇다면 무엇입니까?

또는 언제 사용해도 괜찮 const_cast습니까?



답변

const_cast원래 non- 변수를 캐스팅하는 경우에만 안전합니다 const. 예를 들어 a의 매개 변수를받는 함수가 const char *있고 modifiable을 전달하는 경우 해당 매개 변수를 다시 a 로 수정하고 수정하는 것이 char *안전 합니다. 그러나 원래 변수가 실제로 이면를 사용 하면 정의되지 않은 동작이 발생합니다.const_castchar *constconst_cast

void func(const char *param, size_t sz, bool modify)
{
    if(modify)
        strncpy(const_cast<char *>(param), sz, "new string");
    printf("param: %s\n", param);
}

...

char buffer[16];
const char *unmodifiable = "string constant";
func(buffer, sizeof(buffer), true);  // OK
func(unmodifiable, strlen(unmodifiable), false); // OK
func(unmodifiable, strlen(unmodifiable), true);  // UNDEFINED BEHAVIOR


답변

const_cast가 안전하고 유용한 두 가지 상황을 생각할 수 있습니다 (다른 유효한 경우가있을 수 있음).

하나는 const 인스턴스, 참조 또는 포인터가 있고 const- 올바르지 않은 API에 대한 포인터 또는 참조를 전달하려는 경우이지만 CERTAIN은 개체를 수정하지 않습니다. 포인터를 const_cast하고 API에 전달할 수 있으며 실제로 아무것도 변경되지 않을 것이라고 믿습니다. 예를 들면 :

void log(char* text);   // Won't change text -- just const-incorrect

void my_func(const std::string& message)
{
    log(const_cast<char*>(&message.c_str()));
}

다른 하나는 ‘변경 가능’을 구현하지 않는 이전 컴파일러를 사용하고 있고 논리적으로 const이지만 비트 const가 아닌 클래스를 만들려는 경우입니다. const 메서드 내에서 ‘this’를 const_cast하고 클래스 멤버를 수정할 수 있습니다.

class MyClass
{
    char cached_data[10000]; // should be mutable
    bool cache_dirty;        // should also be mutable

  public:

    char getData(int index) const
    {
        if (cache_dirty)
        {
          MyClass* thisptr = const_cast<MyClass*>(this);
          update_cache(thisptr->cached_data);
        }
        return cached_data[index];
    }
};


답변

이것이 const_cast에 대해 찾을 수 있는 유일한 정보 라는 것이 믿기지 않습니다. 두 번째 Google 히트 곡 에서 인용 :

const로 명시 적으로 선언 된 객체의 constness를 버리고 수정하려고하면 결과가 정의되지 않습니다.

그러나 명시 적으로 const로 선언되지 않은 객체의 constness를 캐스트하면 안전하게 수정할 수 있습니다.


답변

아담이 말하는 것. const_cast가 도움이 될 수있는 또 다른 예 :

struct sample {
    T& getT() { 
        return const_cast<T&>(static_cast<const sample*>(this)->getT()); 
    }

    const T& getT() const { 
       /* possibly much code here */
       return t; 
    }

    T t;
};

우리는 먼저 타입에 const를 추가 this, 우리는의 CONST 버전 전화를 점 getT하고 우리는 이후 유효 반환 형식에서 const를 제거 t그렇지 않으면의 const가 아닌 버전 (const가 아닌 있어야합니다 getT수 없었다 호출되었습니다). 이것은 큰 함수 본문이 있고 중복 코드를 피하려는 경우 매우 유용 할 수 있습니다.


답변

짧은 대답은 ‘아니요’입니다. 안전하지 않습니다.

긴 대답은 당신이 그것을 사용할만큼 충분히 알고 있다면 안전해야한다는 것입니다.

캐스팅 할 때 본질적으로 말하는 것은 “컴파일러가 모르는 것을 알고 있습니다.”입니다. const_cast의 경우 “이 메서드는 상수가 아닌 참조 또는 포인터를 가져 오더라도 전달하는 매개 변수를 변경하지 않을 것임을 알고 있습니다.”라고 말합니다.

따라서 캐스트를 사용하면서 알고 있다고 주장하는 것을 실제로 알고 있다면 사용하는 것이 좋습니다.


답변

컴파일러가 const라고 생각한 것을 수정하기 시작하면 스레드 안전성에서 기회를 파괴하는 것입니다.


답변

#include <iostream>
using namespace std;

void f(int* p) {
  cout << *p << endl;
}

int main(void) {
  const int a = 10;
  const int* b = &a;

  // Function f() expects int*, not const int*
  //   f(b);
  int* c = const_cast<int*>(b);
  f(c);

  // Lvalue is const
  //  *b = 20;

  // Undefined behavior
  //  *c = 30;

  int a1 = 40;
  const int* b1 = &a1;
  int* c1 = const_cast<int*>(b1);

  // Integer a1, the object referred to by c1, has
  // not been declared const
  *c1 = 50;

  return 0;
}

출처 : http://publib.boulder.ibm.com/infocenter/comphelp/v8v101/index.jsp?topic=%2Fcom.ibm.xlcpp8a.doc%2Flanguage%2Fref%2Fkeyword_const_cast.htm