In short: Does the following code have Undefined Behavior, or is this fine?
struct X
{
X(int b)
: value(b)
, ref(value)
{
}
int value;
int& ref;
void isThisUB() const
{
ref = 1;
}
};
int main()
{
const X x(2);
// Is either of these fine?
x.isThisUB();
x.ref = 3;
return x.value;
}
https://godbolt.org/z/1TE9a7M4a
X::value
is const for x
. According to my understanding of const semantics, this means that modifying it in any way is UB. Yet we can take a non-const reference to it in the constructor and then modify it through that, either in a const
member function or directly.
The C++ (at least 17) standard gives an example of const-related UB in [dcl.type.cv] that looks mostly the same, except it employs const_cast
. Note how p->xj = 99
is denoted as UB. I do not see a fundamental difference between achieving this with const_cast
vs my above code.
So, is the code above UB? Are non-const reference members/pointers really this big of a footgun?
(If you can come up with search keywords that yield a related question and not just random const
stuff, I'll be mighty impressed.)
Does the following code have Undefined Behavior, or is this fine?
It has UB. Standard says:
[dcl.type.cv]
Except that any class member declared mutable can be modified, any attempt to modify a const object during its lifetime results in undefined behavior .
x
is const and you modify its non-mutable member.
I do not see a fundamental difference between achieving this with const_cast vs my above code.
Indeed. Both are UB for the same reason.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.