I can\'t find much information on const_cast
. The only info I could find (on Stack Overflow) is:
The
const_cast<>()
i
What Adam says. Another example where const_cast can be helpful:
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;
};
We first add const to the type this
points to, then we call the const version of getT
, and then we remove const from the return type, which is valid since t
must be non-const (otherwise, the non-const version of getT
couldn't have been called). This can be very useful if you got a large function body and you want to avoid redundant code.
I find it hard to believe that that's the only information you could find about const_cast. Quoting from the second Google hit:
If you cast away the constness of an object that has been explicitly declared as const, and attempt to modify it, the results are undefined.
However, if you cast away the constness of an object that has not been explicitly declared as const, you can modify it safely.
The short answer is no, it's not safe.
The long answer is that if you know enough to use it, then it should be safe.
When you're casting, what you are essentially saying is, "I know something the compiler doesn't know." In the case of const_cast, what you are saying is, "Even though this method takes in a non-const reference or pointer, I know that it won't change the parameter I pass it."
So if you do actually know what you are claiming to know in using the cast, then it's fine to use it.
const_cast
is safe only if you're casting a variable that was originally non-const
. For example, if you have a function that takes a parameter of a const char *
, and you pass in a modifiable char *
, it's safe to const_cast
that parameter back to a char *
and modify it. However, if the original variable was in fact const
, then using const_cast
will result in undefined behavior.
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
I can think of two situations where const_cast is safe and useful (there may be other valid cases).
One is when you have a const instance, reference, or pointer, and you want to pass a pointer or reference to an API that is not const-correct, but that you're CERTAIN won't modify the object. You can const_cast the pointer and pass it to the API, trusting that it won't really change anything. For example:
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()));
}
The other is if you're using an older compiler that doesn't implement 'mutable', and you want to create a class that is logically const but not bitwise const. You can const_cast 'this' within a const method and modify members of your class.
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];
}
};
You're destroying any chance at thread-safety, if you start modifying things that the compiler thought were const.