I would like to check my understanding and conclusions on this matter.
On IRC, it was asked:
Is it acceptable to
const_cast
aconst
reference that's bound to a temporary object?
Translating: he has a ref-to-const bound to a temporary, and he wants to cast away its const
-ness to modify it.
My response was that I'd asked a similar question previously, where the consensus seemed to be that temporaries themselves are not inherently const
, and thus that you can cast off the const
-ness of a reference you have to them, and modify them through the result. And, as long as that original ref-to-const
still exists, this won't affect the temporary's lifetime.
That is:
int main()
{
const int& x = int(3);
int& y = const_cast<int&>(x);
y = 4;
cout << x;
}
// Output: 4
// ^ Legal and safe
Am I right?
(Of course, whether or not such code is actually advisable is another matter entirely!)
But const (int&) is a reference int& that is const , meaning that the reference itself cannot be modified.
The benefit of const correctness is that it prevents you from inadvertently modifying something you didn't expect would be modified.
Once you have a const object, it cannot be assigned to a non-const reference or use functions that are known to be capable of changing the state of the object.
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.
No.
First, as far as I can tell, whether it is a literal or not is irrelevant. Rvalues of non-class types always have non-cv qualified types (§3.10/9), however, in §8.5.3 (initialization of a reference), we have:
A reference to type “cv1 T1” is initialized by an expression of type “cv2 T2” as follows:
[...]
--
Otherwise, a temporary of type “cv1 T1” is created and initialized from the initializer expression using the rules for a non-reference copy initialization (8.5). The reference is then bound to the temporary. If T1 is reference-related to T2, cv1 must be the same cv-qualification as, or greater cvqualification than, cv2; otherwise, the program is ill-formed.
(All of the preceding points concern either lvalues or class types.)
In our case, we have:
int const& x = ...;
So cv1 T1 is int const
, and the temporary object we create has type
int const
. This is a top level const (on the object), so any attempt
to modify it is undefined behavior.
At least, that's my interpretation. I wish the standard were a bit clearer about this.
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