In my work the use of const_cast
is under some circumstances unavoidable.
Now I have to const_cast
some pretty complicated types and actually I don't want to write all this type clutter in the const_cast<Clutter>
expressions, especially if Clutter
is very long.
My first idea was to write const_cast<>(myType)
, but my compiler cannot deduce the non-const type of myType
. So I thought about helping my compiler and I deviced the following approach, which compiles.
#include <stdlib.h>
#include <iostream>
int main(int, char**) {
const int constVar = 6;
using T = typename std::remove_cv<decltype(constVar)>::type;
auto& var = const_cast<T&>(constVar);
var *= 2;
std::cout << &constVar << " " << &var << "\n"; // Same address!
std::cout << constVar << " " << var << "\n";
return EXIT_SUCCESS;
}
Unfortunately, the program gives me the output 6 12
instead of the expected 6 6
, which I really didn't understand?
What is wrong with my approach?
From the documentation of const_cast
:
const_cast
makes it possible to form a reference or pointer to non-const type that is actually referring to a const object or a reference or pointer to non-volatile type that is actually referring to a volatile object. Modifying a const object through a non-const access path and referring to a volatile object through a non-volatile glvalue results in undefined behavior.
So what you have is undefined behavior.
Also of interest is this note from cv type qualifiers.
const object - an object whose type is const-qualified, or a non-mutable subobject of a const object. Such object cannot be modified: attempt to do so directly is a compile-time error, and attempt to do so indirectly (e.g., by modifying the const object through a reference or pointer to non-const type) results in undefined behavior.
If you have
void foo(const int& a)
{
const_cast<int&>(a) = 4;
}
then
int a = 1;
foo(a);
is perfectly legal, but
const int a = 1;
foo(a);
invokes an undefined behaviour, because in foo
, a
was originally const
.
This is useful in some case (usually when interfacing old C library), but in most cases, you are doing something wrong and should rethink your solution.
And to answer why const_cast<>
isn't a thing, I'd say for two reasons. First, when you do const_cast
you should really know what you are doing, if some kind of template deduction was allowed, it would make doing unintended mistakes more likely to occur. And secondly const_cast
can also be used to remove volatile
and how can compiler know what you want to cast away?
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With