const_cast는 C++의 특별한 형 변환 연산자이며, 포인터나 참조에서 const/volatile 한정자를 제거하거나 추가할 수 있게 해줍니다. 가장 흔히 사용되는 경우는 객체를 전송하는 함수가 비상수형을 기대할 때, 원래 객체가 const 한정자로 정의된 경우입니다.
사용 예:
const T& 전역에서 전송된 경우), const 특성을 제거한 상태에서 쓰기를 시도하는 것은 정의되지 않은 동작을 초래합니다.void foo(int* p) { *p = 42; } void bar(const int* q) { // const를 제거하는 것은 원래 객체가 비상수일 경우에만! foo(const_cast<int*>(q)); }
bar에 int에 대한 포인터가 전달된다면, 안전하게 const를 제거할 수 있습니다. 만약 const int에 대한 포인터라면, 쓰기 시에 UB가 발생할 것입니다.
mutable로 표시합니다."const_cast를 사용하여 리터럴 또는 읽기 전용 메모리에 있는 객체의 const를 제거할 수 있습니까? 이것이 어떤 위험을 초래합니까?"
답변: 포인터나 참조의 const 특성을 제거할 수는 있지만, 리터럴이나 읽기 전용 세그먼트에 배치된 값을 변경하려고 하면 정의되지 않은 동작이 발생합니다 — 이는 충돌이나 쓰기 무시를 초래할 수 있습니다.
예:
const char* str = "hello"; char* p = const_cast<char*>(str); p[0] = 'H'; // UB: 문자열 리터럴이 읽기 전용 메모리에 있습니다!
이야기
프로젝트에서 필드의 const를 제거한 후, 이러한 필드에 대해 썼고, 전달된 값이 실제로 const (전역 상수)라는 것을 인식하지 못하여 — 애플리케이션이 특정 플랫폼에서 segmentation fault로 충돌했습니다.
이야기
코드에서 const 메서드의 mutable 한정자 없이 const_cast를 사용하여 우회했으며, const 메서드 내에서 클래스 필드를 변경하는 바람에 경쟁 접근 시에 발견하기 어려운 버그가 발생했습니다.
이야기
STL 컨테이너의 객체에 대한 비정상적인 const_cast (예: const std::vector)를 사용한 후, 컨테이너를 수정했으며 — 이는 항상 즉시 오류를 발생시키지는 않지만, 이후 컨테이너 작업에서 예측할 수 없는 동작을 초래합니다.