Does the following program have undefined behavior?
#include <iostream>
#include <vector>
struct Foo
{
const std::vector<int> x;
};
int main()
{
std::vector<int> v = {1,2,3};
auto f = new Foo{v};
const_cast<int&>(f->x[1]) = 42; // Legal?
std::cout << f->x[1] << "\n";
}
Note that it not using const_cast
to strip constness from f->x
, but instead stripping constness from f->x[x]
, which presumably is represented by a separate array. Or is a translation allowed to presume that f->x[1]
is immutable after it is created?
vector<const string>: Cannot change the values of the elements of this vector after they've been added. EDIT: This may fail to compile on a pre-C++11 compiler. const vector<string>: Cannot change anything about the vector.
const_cast is one of the type casting operators. It is used to change the constant value of any object or we can say it is used to remove the constant nature of any object. const_cast can be used in programs that have any object with some constant value which need to be changed occasionally at some point.
The above code does not invoke undefined behavior because the underlying data (int) is mutable. Let's look at a simpler example.
#include <iostream>
struct IntPtr {
int* data;
};
int main() {
int a = 0;
const IntPtr p { &a };
*p.data = 10;
std::cout << a; // Prints 10
}
All of this is perfectly legal to do because making IntPtr
const results in data
being a constant pointer to an int, NOT a pointer to a constant int. We can modify the data that p.data
points to; we just can't modify p.data
itself.
const IntPtr p { &a };
*p.data = 10; // This is legal
int b;
p.data = &b; // This is illegal (can't modify const member)
So how does this example apply to std::vector
?
Let's add the ability to index into an IntPtr
:
class IntPtr {
int* data;
public:
IntPtr() = default;
IntPtr(int size) : data(new int[size]) {}
// Even though this is a const function we can return a mutable reference
// because the stuff data points to is still mutable.
int& operator[](int index) const {
return data[index];
}
};
int main() {
const IntPtr i(100);
i[1] = 10; // This is fine
};
Even though the IntPtr
is const, the underlying data is mutable because it's created by allocating an array of mutable ints. It's the same for std::vector
: the underlying data is still mutable, so it's safe to const_cast
it.
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