Constant value changing

The name of the pictureThe name of the pictureThe name of the pictureClash 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?










share|improve this question

















  • 1




    Yes, it is UB, as c is const.
    – geza
    4 hours ago














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?










share|improve this question

















  • 1




    Yes, it is UB, as c is const.
    – geza
    4 hours ago












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?










share|improve this question













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






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked 5 hours ago









DarthRubik

1,625934




1,625934







  • 1




    Yes, it is UB, as c is const.
    – geza
    4 hours ago












  • 1




    Yes, it is UB, as c 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












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.






share|improve this answer



























    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.






    share|improve this answer


















    • 2




      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










    • But since c->x->z++ is c.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 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




      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 Answer





    StackExchange.ifUsing("editor", function ()
    StackExchange.using("externalEditor", function ()
    StackExchange.using("snippets", function ()
    StackExchange.snippets.init();
    );
    );
    , "code-snippets");

    StackExchange.ready(function()
    var channelOptions =
    tags: "".split(" "),
    id: "1"
    ;
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function()
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled)
    StackExchange.using("snippets", function()
    createEditor();
    );

    else
    createEditor();

    );

    function createEditor()
    StackExchange.prepareEditor(
    heartbeatType: 'answer',
    convertImagesToLinks: true,
    noModals: false,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: 10,
    bindNavPrevention: true,
    postfix: "",
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    );



    );













     

    draft saved


    draft discarded


















    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






























    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.






    share|improve this answer
























      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.






      share|improve this answer






















        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.






        share|improve this answer












        [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.







        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered 4 hours ago









        T.C.

        102k13206310




        102k13206310






















            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.






            share|improve this answer


















            • 2




              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










            • But since c->x->z++ is c.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 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




              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















            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.






            share|improve this answer


















            • 2




              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










            • But since c->x->z++ is c.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 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




              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













            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.






            share|improve this answer














            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.







            share|improve this answer














            share|improve this answer



            share|improve this answer








            edited 4 hours ago

























            answered 5 hours ago









            Stephan Lechner

            22.6k21637




            22.6k21637







            • 2




              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










            • But since c->x->z++ is c.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 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




              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













            • 2




              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










            • But since c->x->z++ is c.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 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




              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








            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


















             

            draft saved


            draft discarded















































             


            draft saved


            draft discarded














            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













































































            Comments

            Popular posts from this blog

            What does second last employer means? [closed]

            Installing NextGIS Connect into QGIS 3?

            One-line joke