Is const_cast safe?

I can not find much information about const_cast . The only information I could find (in Stack Overflow) was:

const_cast<>() used to add / remove the constant (or variability) of a variable.

It makes me nervous. Can using const_cast cause unexpected behavior? If so, then what?

Alternatively, when can const_cast be used?

+84
c ++ casting const-cast
Dec 10 '08 at 21:01
source share
7 answers

const_cast is safe only if you produce a variable that was originally not const . For example, if you have a function that takes a const char * parameter, and you pass the char * modifier, it saves const_cast this parameter back to char * and modifies it. However, if the original variable was actually 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 
+91
Dec 10 '08 at
source share

I can think of two situations where const_cast is safe and useful (there may be other valid cases).

One of them is when you have an instance of const, a link or a pointer, and you want to pass a pointer or a link to an API that is not const-correct, but you CERTAIN will not modify the object. You can const_cast a pointer and pass it to the API, assuming that this will not 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 use an older compiler that does not implement "mutable", and you want to create a class that is logically const, but not a bit constant. You can const_cast 'this' inside the const method and modify the 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]; } }; 
+32
Dec 10 '08 at 21:25
source share

I find it hard to believe that this is the only information you could find about const_cast. A quote from a second google hit :

If you discard an object that was explicitly declared as const and try to modify it, the results are undefined.

However, if you discard the constness of an object that was not explicitly declared as const, you can safely modify it.

+22
Dec 10 '08 at 21:10
source share

What Adam says. Another example where const_cast can be useful:

 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; }; 

First we add const to the type this , then we call the version of const getT , and then we remove the const from the return type, which is valid, since t must be non-constant (otherwise it would not be possible to name the non-constant version of getT ). This can be very useful if you got a large body of the function and want to avoid redundant code.

+10
Dec 10 '08 at 21:17
source share

The short answer is no, it is not safe.

The long answer is: if you know enough to use it, then it should be safe.

When you are casting, you basically say: "I know that the compiler does not know." In the case of const_cast, you say: "Even if this method accepts a non-constant reference or pointer, I know that it will not change the parameter that I pass."

So, if you really know what you are claiming to know using a cast, then it is great to use it.

+8
Dec 10 '08 at 22:39
source share

You are destroying any chance of thread safety if you start changing things that the compiler thought were const.

+5
Dec 10 '08 at 21:16
source share
 #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; } 

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

-one
19 Jul. '12 at 13:41
source share



All Articles