const_cast

why I should used const_cast instead of 'C' style casting?


C style:
1
2
3
const char* str = "String";
char* str1 = (char*)str;
str1="changedString";


Using const_cast:
1
2
3
const char* str = "String";
char* str1 = const_cast<char*>(str);
str1="changedString";



When you are using C++ and not C.
I mean whats the benefit of using const_cast over 'C' style casting?
One benefit is const_cast throw an bad_cast exception if casting not done.

Are there other benefits?
* It is easier to find C++ casts from the code.
* C++ casts are more specific. Less is more.


Your example looks odd.
You have a pointer to a string literal constant.
You make another pointer to that same string literal constant.
You change the second pointer to point to a different string literal constant.
Doesn't your compiler remark about assigning const char* ("changedString") to non-const str1?
I don't see in documentation for const_cast that it throws an exception.

There's generally no reason to use const cast, C-style or otherwise. If it's needed, it suggests a design flaw. However, if you have C++ code that needs to interface with older code that might not have const-correctness, then you might have to use a cast.

Modifying a const object that has had its constness casted away will result in undefined behavior.
C-style casts are prone to errors because they are such a blunt instrument. With C++ casts, you indicate your intention and the compiler can check to see if your intention is legal.

1
2
3
4
5
const char *data = "String".
...
// 100 lines later
char *ip = (int *)data;    // Oops. I though "data" was an array of const ints! No warning!
char *ip = const_cast<int*>data;   // Error. data is chars, not ints. Phew! Saved 10 hrs of debugging! 

Thank you All for reply.
@dhayden,

I like your line:
"With C++ casts, you indicate your intention and the compiler can check to see if your intention is legal."

Your example looks odd,

1
2
3
4
5
6
const char *data = "String";
//...
// 100 lines later
char *ip = (int *)data;    // Oops. I though "data" was an array of const ints! No warning!
char *ip = const_cast<int*>data;   // Error. data is chars, not ints. Phew! Saved 10 hrs of debugging!


 
char *ip = const_cast<int*>data;

Here () is missing for data.
It should be,
 
char *ip = const_cast<int*>(data);


And actual error compiler gave is - "A const_cast only adjust type qualifier; it can not change the underlying datatype"

And I did not get,
If coder though "data" was an array of const ints, why *ip is of char type?
@Ganado
I agreed what you said.

But in below example i found const_cast helpful, But yes As you said Its not a good idea to use it.

1
2
3
4
5
int a = 10;
const int* ptr = &a;
char* str3 = (char*)ptr;  // No compile time error
cout<<*str3<<endl;	     // Nothing will print, i.e. Its behavior will be dangerous 
//char* str4 = const_cast<char*>(ptr);  // Compile Error::Not allowed to cast int pointer to char pointer 
Last edited on
Yea, I really botched that example. What I meant was
int *ip = const_cast<int*>(data);
Here's you're saying "I'm casting away the const-ness" but in reality you're doing more.
why I should used const_cast instead of 'C' style casting?


C style cast will do not just const_cast but also static_cast and reinterpret_cast if needed.

C style cast can perform any combination of the above 3 casts and in some of cases you won't notice what kind and in which order the cast(s) were performed.

C style cast may thus perform a cast which you didn't want to happen which usually means a bug.

With C++ style cast this is not possible, because you need to explicitly apply casts(s) you want/need, also the order of casts is explicit too.

conclusion:
C-style cast means: do what ever is needed, even if wrong.
C++ style cast means: do exactly as I say.
Last edited on
Imho such C code is just too weak const convert it to non-const easily on run time without checking more at compile time,
it's like this http://www.cplusplus.com/forum/general/266567/
@abdulbadii,
I did not find any issue with the code mentioned in the post.
http://www.cplusplus.com/forum/general/266567/

@malibor,
Thanks. I agreed what you said.
Additionally, In case of dynamic_casting it throws and bad_cast exception.


@keskiverto,
No error from compiler for given example code.
Why should I use const_cast instead of 'C' style casting?

This is just anecdotal, but the code I write uses type conversions most frequently on the boundary of first-party and unfamiliar third-party code. These library boundaries are exactly where the type system is most effective at preventing mistakes.

While C++-style type conversions aren't perfectly safe, C-style conversions represent an almost-complete subversion of the type system. These conversions appear right where type checking is most crucial. To me, the choice is clear. I strongly prefer C++-style conversions because they are less error-prone.

Last edited on
Additionally, In case of dynamic_casting it throws and bad_cast exception.


C-style cast does not perform run time polymorphic conversion, that is, it never does dynamic_cast, because C language doesn't use polymorphism.

Few examples what happesn:

1. When you use C style cast on base type and attempt to cast it to unrelated derived type or vice versa, what happens behind the scene is reinterpret_cast, and using such returned pointer is undefined behavior and not std::bad_cast as you are expecting. it succeeds where dynamic_cast would fail!

2. Another example, when you use C style cast on base type and attempt to cast it to derived type, what happens behind the scene is static_cast, and using such returned pointer is again undefined behavior and not std::bad_cast as you are expecting.

3. However if you cast from derived type to base type then again static_cast is performed, and if needed to cast const away then const_cast is performed too, This last case is not necesarily undefined behavior, unless your derived type has multiple bases, with common abstract base, so again C style cast is bad here too, becuase dynamic_cast would perform side cast in this case while C style cast would not!

In all cases above, const_cast is automatically performed if needed!
Last edited on
C++ casts are the way to go. I admittedly use C casts because its one of a hundred things I should unlearn from decades back and little by little I am trying to break the habits. The 'new' ones are bloated and the reuse of template syntax is almost as bad as the stream setting 'functions' (setw, etc) that look like variables. Sigh. Whoever came up with the syntax needs a stern talking to, but they were necessary and are far superior tools.
The 'new' ones are bloated and the reuse of template syntax is almost as bad as the stream setting 'functions' (setw, etc) that look like variables.

I'm with you about setw and friends, but what's wrong with reusing the template syntax? IIRC, this was deliberate so that library code like std::duration_cast, boost::lexical_cast look like the built-in conversions.
Last edited on
there is nothing 'wrong' with it but to cast a freaking double to an int should not require 30 characters to express. They evaluated everything except ... how huge the text is... when making their choice. And, if you are reading the code quickly in something without a syntax highlight, it looks like template/stl stuff so you have to do a double take. Like a grep dump of a block. granted maybe we are past such tools.

I won't try to claim I could do it better, but I still don't really care for what we got. The temptation to macro it up at times is like an itch you should not scratch.
Last edited on
Topic archived. No new replies allowed.