Constant value changing
Clash Royale CLAN TAG#URR8PPP
up vote
7
down vote
favorite
Suppose I have a struct definition:
struct thing
thing* x;
int z;
thing() : x(this), z(0)
void foo() const
this->x->z++;
;
Note that I create a mutable pointer to myself (evil laugh)
And then I can use this later like this:
int main()
const thing c;
c.foo();
assert(c.z == 1);
c.foo();
assert(c.z == 2);
return c.z;
And as you can see it seems that I can change a constant value......is this UB?
c++ const undefined-behavior
add a comment |Â
up vote
7
down vote
favorite
Suppose I have a struct definition:
struct thing
thing* x;
int z;
thing() : x(this), z(0)
void foo() const
this->x->z++;
;
Note that I create a mutable pointer to myself (evil laugh)
And then I can use this later like this:
int main()
const thing c;
c.foo();
assert(c.z == 1);
c.foo();
assert(c.z == 2);
return c.z;
And as you can see it seems that I can change a constant value......is this UB?
c++ const undefined-behavior
1
Yes, it is UB, asc
is const.
â geza
4 hours ago
add a comment |Â
up vote
7
down vote
favorite
up vote
7
down vote
favorite
Suppose I have a struct definition:
struct thing
thing* x;
int z;
thing() : x(this), z(0)
void foo() const
this->x->z++;
;
Note that I create a mutable pointer to myself (evil laugh)
And then I can use this later like this:
int main()
const thing c;
c.foo();
assert(c.z == 1);
c.foo();
assert(c.z == 2);
return c.z;
And as you can see it seems that I can change a constant value......is this UB?
c++ const undefined-behavior
Suppose I have a struct definition:
struct thing
thing* x;
int z;
thing() : x(this), z(0)
void foo() const
this->x->z++;
;
Note that I create a mutable pointer to myself (evil laugh)
And then I can use this later like this:
int main()
const thing c;
c.foo();
assert(c.z == 1);
c.foo();
assert(c.z == 2);
return c.z;
And as you can see it seems that I can change a constant value......is this UB?
c++ const undefined-behavior
c++ const undefined-behavior
asked 5 hours ago
DarthRubik
1,625934
1,625934
1
Yes, it is UB, asc
is const.
â geza
4 hours ago
add a comment |Â
1
Yes, it is UB, asc
is const.
â geza
4 hours ago
1
1
Yes, it is UB, as
c
is const.â geza
4 hours ago
Yes, it is UB, as
c
is const.â geza
4 hours ago
add a comment |Â
2 Answers
2
active
oldest
votes
up vote
7
down vote
accepted
[dcl.type.cv]p4:
Except that any class member declared
mutable
([dcl.stc]) can be
modified, any attempt to modify ([expr.ass], [expr.post.incr],
[expr.pre.incr]) a const object ([basic.type.qualifier]) during its
lifetime ([basic.life]) results in undefined behavior.
[basic.type.qualifier]p1:
A const object is an object of type
const T
or a non-mutable subobject of such an object.
c.z
is a const object, because it is a non-mutable subobject of c
. Your code attempts to modify it during its lifetime. It follows that the code has undefined behavior.
add a comment |Â
up vote
0
down vote
The foo
-function itself would be OK, as const
member functions like T::foo() const
just indicate that this
is of type const *T
; The fact that a (non-const) member points to the same object is irrelevant then.
The object c
in first place, however, is declared as const. So it is UB to alter the contents of c
through whatever code, including the (per se correct) member function foo
.
2
What about the fact thatc
isconst
?
â NathanOliver
5 hours ago
@NathanOliver: yes; you may not change the value ofc->x
, but you may change the object referenced byc->x
; soc->x->z++
is valid even ifc
is const.
â Stephan Lechner
5 hours ago
But sincec->x->z++
isc.z++
isn't that UB?
â NathanOliver
5 hours ago
1
@NathanOliver: No, I'm quite sure that it is not UB.const
does not mean that the object is immutable in general; it just declares that it must not be changed through the (const) pointer at hand. So you cannot changez
through a(const*) this->z++
, but through another path to that object, i.e. throughthis->x->z++
â Stephan Lechner
5 hours ago
1
Your example is only valid becausevalue
was not declared const in the first place.. but histhing
instance is declared const.. and if you attempted toconst_cast<thing*>(this)->z++;
it'd be undefined behaviour.. So why would he be able to modify it through a shallow copy ofthis
.. *Note:( I did not downvote.
â Brandon
5 hours ago
 |Â
show 2 more comments
2 Answers
2
active
oldest
votes
2 Answers
2
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
7
down vote
accepted
[dcl.type.cv]p4:
Except that any class member declared
mutable
([dcl.stc]) can be
modified, any attempt to modify ([expr.ass], [expr.post.incr],
[expr.pre.incr]) a const object ([basic.type.qualifier]) during its
lifetime ([basic.life]) results in undefined behavior.
[basic.type.qualifier]p1:
A const object is an object of type
const T
or a non-mutable subobject of such an object.
c.z
is a const object, because it is a non-mutable subobject of c
. Your code attempts to modify it during its lifetime. It follows that the code has undefined behavior.
add a comment |Â
up vote
7
down vote
accepted
[dcl.type.cv]p4:
Except that any class member declared
mutable
([dcl.stc]) can be
modified, any attempt to modify ([expr.ass], [expr.post.incr],
[expr.pre.incr]) a const object ([basic.type.qualifier]) during its
lifetime ([basic.life]) results in undefined behavior.
[basic.type.qualifier]p1:
A const object is an object of type
const T
or a non-mutable subobject of such an object.
c.z
is a const object, because it is a non-mutable subobject of c
. Your code attempts to modify it during its lifetime. It follows that the code has undefined behavior.
add a comment |Â
up vote
7
down vote
accepted
up vote
7
down vote
accepted
[dcl.type.cv]p4:
Except that any class member declared
mutable
([dcl.stc]) can be
modified, any attempt to modify ([expr.ass], [expr.post.incr],
[expr.pre.incr]) a const object ([basic.type.qualifier]) during its
lifetime ([basic.life]) results in undefined behavior.
[basic.type.qualifier]p1:
A const object is an object of type
const T
or a non-mutable subobject of such an object.
c.z
is a const object, because it is a non-mutable subobject of c
. Your code attempts to modify it during its lifetime. It follows that the code has undefined behavior.
[dcl.type.cv]p4:
Except that any class member declared
mutable
([dcl.stc]) can be
modified, any attempt to modify ([expr.ass], [expr.post.incr],
[expr.pre.incr]) a const object ([basic.type.qualifier]) during its
lifetime ([basic.life]) results in undefined behavior.
[basic.type.qualifier]p1:
A const object is an object of type
const T
or a non-mutable subobject of such an object.
c.z
is a const object, because it is a non-mutable subobject of c
. Your code attempts to modify it during its lifetime. It follows that the code has undefined behavior.
answered 4 hours ago
T.C.
102k13206310
102k13206310
add a comment |Â
add a comment |Â
up vote
0
down vote
The foo
-function itself would be OK, as const
member functions like T::foo() const
just indicate that this
is of type const *T
; The fact that a (non-const) member points to the same object is irrelevant then.
The object c
in first place, however, is declared as const. So it is UB to alter the contents of c
through whatever code, including the (per se correct) member function foo
.
2
What about the fact thatc
isconst
?
â NathanOliver
5 hours ago
@NathanOliver: yes; you may not change the value ofc->x
, but you may change the object referenced byc->x
; soc->x->z++
is valid even ifc
is const.
â Stephan Lechner
5 hours ago
But sincec->x->z++
isc.z++
isn't that UB?
â NathanOliver
5 hours ago
1
@NathanOliver: No, I'm quite sure that it is not UB.const
does not mean that the object is immutable in general; it just declares that it must not be changed through the (const) pointer at hand. So you cannot changez
through a(const*) this->z++
, but through another path to that object, i.e. throughthis->x->z++
â Stephan Lechner
5 hours ago
1
Your example is only valid becausevalue
was not declared const in the first place.. but histhing
instance is declared const.. and if you attempted toconst_cast<thing*>(this)->z++;
it'd be undefined behaviour.. So why would he be able to modify it through a shallow copy ofthis
.. *Note:( I did not downvote.
â Brandon
5 hours ago
 |Â
show 2 more comments
up vote
0
down vote
The foo
-function itself would be OK, as const
member functions like T::foo() const
just indicate that this
is of type const *T
; The fact that a (non-const) member points to the same object is irrelevant then.
The object c
in first place, however, is declared as const. So it is UB to alter the contents of c
through whatever code, including the (per se correct) member function foo
.
2
What about the fact thatc
isconst
?
â NathanOliver
5 hours ago
@NathanOliver: yes; you may not change the value ofc->x
, but you may change the object referenced byc->x
; soc->x->z++
is valid even ifc
is const.
â Stephan Lechner
5 hours ago
But sincec->x->z++
isc.z++
isn't that UB?
â NathanOliver
5 hours ago
1
@NathanOliver: No, I'm quite sure that it is not UB.const
does not mean that the object is immutable in general; it just declares that it must not be changed through the (const) pointer at hand. So you cannot changez
through a(const*) this->z++
, but through another path to that object, i.e. throughthis->x->z++
â Stephan Lechner
5 hours ago
1
Your example is only valid becausevalue
was not declared const in the first place.. but histhing
instance is declared const.. and if you attempted toconst_cast<thing*>(this)->z++;
it'd be undefined behaviour.. So why would he be able to modify it through a shallow copy ofthis
.. *Note:( I did not downvote.
â Brandon
5 hours ago
 |Â
show 2 more comments
up vote
0
down vote
up vote
0
down vote
The foo
-function itself would be OK, as const
member functions like T::foo() const
just indicate that this
is of type const *T
; The fact that a (non-const) member points to the same object is irrelevant then.
The object c
in first place, however, is declared as const. So it is UB to alter the contents of c
through whatever code, including the (per se correct) member function foo
.
The foo
-function itself would be OK, as const
member functions like T::foo() const
just indicate that this
is of type const *T
; The fact that a (non-const) member points to the same object is irrelevant then.
The object c
in first place, however, is declared as const. So it is UB to alter the contents of c
through whatever code, including the (per se correct) member function foo
.
edited 4 hours ago
answered 5 hours ago
Stephan Lechner
22.6k21637
22.6k21637
2
What about the fact thatc
isconst
?
â NathanOliver
5 hours ago
@NathanOliver: yes; you may not change the value ofc->x
, but you may change the object referenced byc->x
; soc->x->z++
is valid even ifc
is const.
â Stephan Lechner
5 hours ago
But sincec->x->z++
isc.z++
isn't that UB?
â NathanOliver
5 hours ago
1
@NathanOliver: No, I'm quite sure that it is not UB.const
does not mean that the object is immutable in general; it just declares that it must not be changed through the (const) pointer at hand. So you cannot changez
through a(const*) this->z++
, but through another path to that object, i.e. throughthis->x->z++
â Stephan Lechner
5 hours ago
1
Your example is only valid becausevalue
was not declared const in the first place.. but histhing
instance is declared const.. and if you attempted toconst_cast<thing*>(this)->z++;
it'd be undefined behaviour.. So why would he be able to modify it through a shallow copy ofthis
.. *Note:( I did not downvote.
â Brandon
5 hours ago
 |Â
show 2 more comments
2
What about the fact thatc
isconst
?
â NathanOliver
5 hours ago
@NathanOliver: yes; you may not change the value ofc->x
, but you may change the object referenced byc->x
; soc->x->z++
is valid even ifc
is const.
â Stephan Lechner
5 hours ago
But sincec->x->z++
isc.z++
isn't that UB?
â NathanOliver
5 hours ago
1
@NathanOliver: No, I'm quite sure that it is not UB.const
does not mean that the object is immutable in general; it just declares that it must not be changed through the (const) pointer at hand. So you cannot changez
through a(const*) this->z++
, but through another path to that object, i.e. throughthis->x->z++
â Stephan Lechner
5 hours ago
1
Your example is only valid becausevalue
was not declared const in the first place.. but histhing
instance is declared const.. and if you attempted toconst_cast<thing*>(this)->z++;
it'd be undefined behaviour.. So why would he be able to modify it through a shallow copy ofthis
.. *Note:( I did not downvote.
â Brandon
5 hours ago
2
2
What about the fact that
c
is const
?â NathanOliver
5 hours ago
What about the fact that
c
is const
?â NathanOliver
5 hours ago
@NathanOliver: yes; you may not change the value of
c->x
, but you may change the object referenced by c->x
; so c->x->z++
is valid even if c
is const.â Stephan Lechner
5 hours ago
@NathanOliver: yes; you may not change the value of
c->x
, but you may change the object referenced by c->x
; so c->x->z++
is valid even if c
is const.â Stephan Lechner
5 hours ago
But since
c->x->z++
is c.z++
isn't that UB?â NathanOliver
5 hours ago
But since
c->x->z++
is c.z++
isn't that UB?â NathanOliver
5 hours ago
1
1
@NathanOliver: No, I'm quite sure that it is not UB.
const
does not mean that the object is immutable in general; it just declares that it must not be changed through the (const) pointer at hand. So you cannot change z
through a (const*) this->z++
, but through another path to that object, i.e. through this->x->z++
â Stephan Lechner
5 hours ago
@NathanOliver: No, I'm quite sure that it is not UB.
const
does not mean that the object is immutable in general; it just declares that it must not be changed through the (const) pointer at hand. So you cannot change z
through a (const*) this->z++
, but through another path to that object, i.e. through this->x->z++
â Stephan Lechner
5 hours ago
1
1
Your example is only valid because
value
was not declared const in the first place.. but his thing
instance is declared const.. and if you attempted to const_cast<thing*>(this)->z++;
it'd be undefined behaviour.. So why would he be able to modify it through a shallow copy of this
.. *Note:( I did not downvote.â Brandon
5 hours ago
Your example is only valid because
value
was not declared const in the first place.. but his thing
instance is declared const.. and if you attempted to const_cast<thing*>(this)->z++;
it'd be undefined behaviour.. So why would he be able to modify it through a shallow copy of this
.. *Note:( I did not downvote.â Brandon
5 hours ago
 |Â
show 2 more comments
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f52710231%2fconstant-value-changing%23new-answer', 'question_page');
);
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
1
Yes, it is UB, as
c
is const.â geza
4 hours ago