change a constant by pointer

Discussion in 'C++' started by want.to.be.professer, Nov 8, 2008.

  1. #include <iostream>
    using namespace std;

    // Check if N is constant
    template <int N>
    class ValidateConstInt{};

    int main()
    {
    const int constValue = 12;
    const int* pConstValue = &constValue;
    int* pValue = const_cast <int*> ( &constValue );

    ValidateConstInt <constValue> (); // Check if constValue is
    constant

    cout << "------------------------------------ " << endl;
    cout << " begin: " << endl;
    cout << "\t const int constValue = 12; " << endl;
    cout << "\t const int* pConstValue = &constValue;"<< endl;
    cout << "\t int* pValue = const_cast <int*> (&ConstValue);"<<
    endl;
    cout << endl;

    cout << "------------------------------------ " << endl;
    cout << " constValue = " << constValue << endl;
    cout << " &constValue = " << &constValue << endl;
    cout << " *pConstValue = " << *pConstValue << endl;
    cout << " pConstValue = " << pConstValue << endl;
    cout << " *pValue = " << *pValue << endl;
    cout << " pValue = " << pValue << endl;
    cout << endl;

    *pValue = 1; // Change the value

    cout << "------------------------------------- After *pValue = 1
    " << endl;
    cout << endl;

    cout << " constValue = " << constValue << endl;
    cout << " &constValue = " << &constValue << endl;
    cout << " *pConstValue = " << *pConstValue << endl;
    cout << " pConstValue = " << pConstValue << endl;
    cout << " *pValue = " << *pValue << endl;
    cout << " pValue = " << pValue << endl;
    cout << "------------------------------------ " << endl;
    return 0;
    }

    // ------------- Result:
    ------------------------------------
    begin:
    const int constValue = 12;
    const int* pConstValue = &constValue;
    int* pValue = const_cast <int*> (&ConstValue);

    ------------------------------------
    constValue = 12
    &constValue = 0012FF6C
    *pConstValue = 12
    pConstValue = 0012FF6C
    *pValue = 12
    pValue = 0012FF6C

    ------------------------------------- After *pValue = 1

    constValue = 12 // not changed
    &constValue = 0012FF6C
    *pConstValue = 1 // have changed
    pConstValue = 0012FF6C
    *pValue = 1 // have changed
    pValue = 0012FF6C
    ------------------------------------

    The pConstValue and pValue both point to the ConstValue, and the value
    access by the point is changed, but constValue has never changed ( and
    it shoule not be a constant ). I can not explain, Can somebody help
    me ?
    want.to.be.professer, Nov 8, 2008
    #1
    1. Advertising

  2. want.to.be.professer

    maverik Guest

    I try the next:

    ....
    > int main()
    > {

    int x = 12;
    >      const int  constValue  = X;
    >      const int* pConstValue = &constValue;
    >      int*       pValue      = const_cast <int*> ( &constValue );
    >

    ....

    And get compiler error:
    'ValidateConstInt' : template parameter 'N' : 'constValue' : a local
    variable cannot be used as a non-type argument

    Perhaps in your case compiler doesn't create constValue, it just uses
    its value: 12 (kind of optimization). So you get such a result. By I'm
    not shure.
    maverik, Nov 8, 2008
    #2
    1. Advertising

  3. -----BEGIN PGP SIGNED MESSAGE-----
    Hash: SHA1

    want.to.be.professer wrote:
    <snip>
    > The pConstValue and pValue both point to the ConstValue, and the value
    > access by the point is changed, but constValue has never changed ( and
    > it shoule not be a constant ). I can not explain, Can somebody help
    > me ?


    According to paragraph 7.1.5.1/4:
    "(...) any attempt to modify a const object during its lifetime results
    in undefined behavior."
    That's why you get that. In fact you compiler optimized constValue, and
    put its value to the parts where it was directly used. In other cases
    (referencing to constValue through pointers) it was treated as a pointer
    to non-cv-qualified object.

    Pawel Dziepak
    -----BEGIN PGP SIGNATURE-----
    Version: GnuPG v1.4.9 (GNU/Linux)
    Comment: Using GnuPG with Fedora - http://enigmail.mozdev.org

    iEYEARECAAYFAkkVhjwACgkQPFW+cUiIHNq59ACdGcVJEcVFYYpUeGbAJ/hEwYMn
    7QgAnR2pxba7gWy4eQHDnTKPfTBe8uTI
    =fRhq
    -----END PGP SIGNATURE-----
    Pawel Dziepak, Nov 8, 2008
    #3
  4. On 11ÔÂ8ÈÕ, ÏÂÎç8ʱ13·Ö, maverik <> wrote:
    > I try the next:
    >
    > ...> int main()
    > > {

    >
    > int x = 12;> const int constValue = X;
    > > const int* pConstValue = &constValue;
    > > int* pValue = const_cast <int*> ( &constValue );

    >
    > ...
    >
    > And get compiler error:
    > 'ValidateConstInt' : template parameter 'N' : 'constValue' : a local
    > variable cannot be used as a non-type argument
    >
    > Perhaps in your case compiler doesn't create constValue, it just uses
    > its value: 12 (kind of optimization). So you get such a result. By I'm
    > not shure.


    In my windows XP OS, I used vs2005 and g++ compiler.They both like
    this.
    want.to.be.professer, Nov 8, 2008
    #4
  5. On 2008-11-08 12:52, want.to.be.professer wrote:
    > #include <iostream>
    > using namespace std;
    >
    > // Check if N is constant
    > template <int N>
    > class ValidateConstInt{};
    >
    > int main()
    > {
    > const int constValue = 12;
    > const int* pConstValue = &constValue;
    > int* pValue = const_cast <int*> ( &constValue );
    >
    > ValidateConstInt <constValue> (); // Check if constValue is
    > constant
    >
    > cout << "------------------------------------ " << endl;
    > cout << " begin: " << endl;
    > cout << "\t const int constValue = 12; " << endl;
    > cout << "\t const int* pConstValue = &constValue;"<< endl;
    > cout << "\t int* pValue = const_cast <int*> (&ConstValue);"<<
    > endl;
    > cout << endl;
    >
    > cout << "------------------------------------ " << endl;
    > cout << " constValue = " << constValue << endl;
    > cout << " &constValue = " << &constValue << endl;
    > cout << " *pConstValue = " << *pConstValue << endl;
    > cout << " pConstValue = " << pConstValue << endl;
    > cout << " *pValue = " << *pValue << endl;
    > cout << " pValue = " << pValue << endl;
    > cout << endl;
    >
    > *pValue = 1; // Change the value
    >
    > cout << "------------------------------------- After *pValue = 1
    > " << endl;
    > cout << endl;
    >
    > cout << " constValue = " << constValue << endl;
    > cout << " &constValue = " << &constValue << endl;
    > cout << " *pConstValue = " << *pConstValue << endl;
    > cout << " pConstValue = " << pConstValue << endl;
    > cout << " *pValue = " << *pValue << endl;
    > cout << " pValue = " << pValue << endl;
    > cout << "------------------------------------ " << endl;
    > return 0;
    > }
    >
    > // ------------- Result:
    > ------------------------------------
    > begin:
    > const int constValue = 12;
    > const int* pConstValue = &constValue;
    > int* pValue = const_cast <int*> (&ConstValue);
    >
    > ------------------------------------
    > constValue = 12
    > &constValue = 0012FF6C
    > *pConstValue = 12
    > pConstValue = 0012FF6C
    > *pValue = 12
    > pValue = 0012FF6C
    >
    > ------------------------------------- After *pValue = 1
    >
    > constValue = 12 // not changed
    > &constValue = 0012FF6C
    > *pConstValue = 1 // have changed
    > pConstValue = 0012FF6C
    > *pValue = 1 // have changed
    > pValue = 0012FF6C
    > ------------------------------------
    >
    > The pConstValue and pValue both point to the ConstValue, and the value
    > access by the point is changed, but constValue has never changed ( and
    > it shoule not be a constant ). I can not explain, Can somebody help
    > me ?


    One of the reasons we have constants is that they allow for certain
    optimisations. Since the compiler knows the value of constValue it can
    skip a lot of stuff it would have to do if it was a variable. If you had
    not taken its address the compiler would probably not allocated the
    memory for it at all and used the value of 12 wherever constValue was
    used. But since you took the its address it had to allocate some memory
    for it, but since it knew it was constant it still didn't bother to use
    it and did the optimisations anyway.

    Notice also that what you did (taking the address of a constant, casting
    away the const-ness and using the pointer to change the value) is not
    allowed, and with other settings / compiler / OS your program would have
    crashed instead because constValue would have been places in read only
    memory. In sort, if you do not follow the rules of the languages
    anything can happen and no guarantees are given.

    --
    Erik Wikström
    Erik Wikström, Nov 8, 2008
    #5
  6. want.to.be.professer

    maverik Guest

    > Notice also that what you did (taking the address of a constant, casting
    > away the const-ness and using the pointer to change the value) is not
    > allowed, and with other settings / compiler / OS your program would have
    > crashed instead because constValue would have been places in read only
    > memory.


    Proof:

    write

    static const int constValue = 12;

    instead of

    const int constValue = 12;

    The program crashes in this case (WinXP SP1, VC8.0) with exception
    that says that I try to write to readonly memory
    maverik, Nov 8, 2008
    #6
  7. want.to.be.professer

    JaredGrubb Guest


    > The pConstValue and pValue both point to the ConstValue, and the value
    > access by the point is changed, but constValue has never changed ( and
    > it shoule not be a constant ). I can not explain, Can somebody help
    > me ?


    You're confusing what "const" means... Const means "you cannot change
    it" and does NOT mean that "it cannot be changed" (your program is an
    example of this!). Change these declarations from "const" to "volatile
    const" and your program will work the way you had hoped (constValue
    returns 1 after *pValue is altered):

    > volatile const int constValue = 12;
    > volatile const int* pConstValue = &constValue;
    JaredGrubb, Nov 9, 2008
    #7
  8. want.to.be.professer

    James Kanze Guest

    On Nov 9, 4:40 pm, JaredGrubb <> wrote:
    > > The pConstValue and pValue both point to the ConstValue, and
    > > the value access by the point is changed, but constValue has
    > > never changed ( and it shoule not be a constant ). I can not
    > > explain, Can somebody help me ?


    > You're confusing what "const" means... Const means "you cannot
    > change it" and does NOT mean that "it cannot be changed" (your
    > program is an example of this!).


    It depends. Const has two meanings. In general, you cannot
    modify a value throw an expression which refers to an object (an
    lvalue expression, in standardese) and has a const type; you can
    modify the object through other expressions, however. If the
    object itself is const, however (as is the case here), any
    attempt to modify it is undefined behavior.

    > Change these declarations from "const" to "volatile const" and
    > your program will work the way you had hoped (constValue
    > returns 1 after *pValue is altered):


    It might, or it might not. Undefined behavior is undefined
    behavior.

    > > volatile const int constValue = 12;
    > > volatile const int* pConstValue = &constValue;


    The volatile simply tells the compiler that this object might be
    modified by something outside the program. Any attempt to
    modify it from within the program is still undefined behavior.
    As another poster pointed out, declaring the object static could
    very well end up in the attempt to modify it causes a core dump.
    The volatile probably won't help here.

    --
    James Kanze (GABI Software) email:
    Conseils en informatique orientée objet/
    Beratung in objektorientierter Datenverarbeitung
    9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
    James Kanze, Nov 10, 2008
    #8
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Fraser Ross
    Replies:
    4
    Views:
    1,026
    Fraser Ross
    Aug 14, 2004
  2. Christopher M. Lusardi
    Replies:
    1
    Views:
    4,074
  3. Martin Magnusson
    Replies:
    2
    Views:
    492
    John Harrison
    Oct 8, 2004
  4. Tor Erik Soenvisen
    Replies:
    14
    Views:
    545
    Tim Roberts
    Nov 23, 2006
  5. G G
    Replies:
    3
    Views:
    79
    Ben Bacarisse
    Apr 20, 2014
Loading...

Share This Page