Search This Blog

Friday, January 22, 2010

C++ Change value of const int

This is interesting question -

I have following statement in C++ program -
const int a = 22;

and I want to change the value of a to some other value.


////////////////////////////////////////////////////////////////////////////////////////////////

I tried following code -
#include

using namespace std;

int main() {

const int a = 22;

const int *ptr_to_a = &a;
int *ptr;
ptr = (int*)ptr_to_a;

(*ptr) = 5;
cout << style="color: rgb(0, 153, 0);">// Prints 22 => Visual studio 2005 and 2008 debugger shows value of a 5!

const int &b = a;
cout << class="blsp-spelling-error" id="SPELLING_ERROR_12">endl; // Prints 5

int c = a;
cout << class="blsp-spelling-error" id="SPELLING_ERROR_14">endl; // Prints 22

return 0;
}

////////////////////////////////////////////////////////////////////////////////////////////////

Looking at the above code. I thought this problem is compiler dependent. But Visual Studio 2005 and 2008 do not give any warning, rather (I confidently dare to say that) this is bug in Visual Studio that it shows value of a 5 after "(*ptr) = 5;" (in debugger), but prints 22!
The problem is probably not compiler dependent because I got same output 22, 5, 22 using GCC (g++) compiler (I tried this on Cywgin - 32 bit Windows XP and 64 Bit Linux).

Probably the simple and logical answer to this question is - you can not change the value of "const int a".

Note I have also tried tricks like -
int *ptr = (int*)&a;
and
int *ptr = const_cast(ptr_to_a);

If you have any solution please post it in comments.

12 comments:

  1. Not a solution but some more interesting code

    #include

    using namespace std;

    void IChangeConst(int* pa) {
    *pa = 5;
    cout << "IChangeConst: *pa : " << *pa << endl;
    }

    int main() {

    const int a = 22;
    int *ptr = (int*)&a;

    IChangeConst(ptr);
    cout << "Value of a after IChangeConst : " << a << endl;

    const int &b = a;
    cout << "Value of b which is reference to a :" << b << endl;

    int c = a;
    cout << "Valu of C - equal to value of a : " << c << endl;

    return 0;
    }

    // Output using GCC 4.4.1 (Linux - Fedora11 64bit).
    IChangeConst: *pa : 5
    Value of a after IChangeConst : 22
    Value of b which is reference to a :5
    Valu of C - equal to value of a : 22

    ReplyDelete
  2. // Finally the solution - though not exactly a solution // because I had to use volatile keyword here in
    // addition. Thanks to Ali Dar

    #include

    using namespace std;

    int main() {

    volatile const int a = 22;
    const volatile int *ptr_to_a = &a;
    int *ptr;

    ptr = (int*)ptr_to_a;
    (*ptr) = 5;

    cout << a << endl;
    // Prints 5

    volatile const int &b = a;

    cout << b << endl;
    // Prints 5

    int c = a;

    cout << c << endl;
    // Prints 22

    return 0;
    }

    // Output
    5
    5
    5

    ReplyDelete
  3. // Another solution using function - again Would be great
    // if I could avoid volatile keyword

    #include

    using namespace std;

    void IChangeConst(int* pa) {
    *pa = 5;
    cout << "IChangeConst: *pa : " << *pa << endl;
    }



    int main() {
    volatile const int a = 22;

    int *ptr = (int*)&a;
    IChangeConst(ptr);
    cout << "Value of a after IChangeConst : " << a << endl;

    volatile const int &b = a;
    cout << "Value of b which is reference to a :" << b << endl;

    int c = a;
    cout << "Valu of C - equal to value of a : " << c << endl;
    return 0;

    }

    // Output
    IChangeConst: *pa : 5
    Value of a after IChangeConst : 5
    Value of b which is reference to a :5
    Valu of C - equal to value of a : 5

    ReplyDelete
  4. Ashish...good work.. I have studied modifying const variables in past (3dplm) .. Here are tricks..

    1. In case of simple data types compiler probably inlines these variables everywhere in their respective scope... That is why you get actual const value and not modified one.

    2. But const pointer as well as const reference can easily be modified.

    3. const class variables are much easy to modify.

    Following code and output should tell the story!


    #include "stdio.h"

    int * donothing(const int * p,const int &pdummy);

    class data
    {
    public:
    int aa;
    data(int i): aa(i)
    {
    }
    };

    int main(int argc,char *argv[])
    {
    const int a=10;

    int *b=donothing(&a,a);

    printf("after do nothing value at pointer pointing to a is %d\n",*b);


    //OK now some tests with classes.

    const data xyz(10);
    //xyz.aa=1; THIS is not allowed....

    const data* aaa=&xyz;

    data* bbb=(data*)aaa;

    //data

    bbb->aa=100;

    printf("class a value %d\n",xyz.aa);


    return 0;
    }

    int * donothing(const int * p,const int &pdummy)
    {
    int *c=(int*)p;

    *c=100;
    printf("In do nothing value of a is %d\n",pdummy);

    return c;
    }

    OUTPUT:

    In do nothing value of a is 100
    after do nothing value at pointer pointing to a is 100
    class a value 100

    Vivek Jadye

    ReplyDelete
  5. Thank you for help Vivek.
    I added 2 more printf statements in your code to check it "const int a" is getting change or not - it is not :(

    #include "stdio.h"

    int * donothing(const int * p,const int &pdummy);

    class data
    {
    public:
    int aa;
    data(int i): aa(i)
    {
    }
    };

    int main(int argc,char *argv[])
    {
    const int a=10;

    printf("before do nothing value of a is %d\n",a);

    int *b=donothing(&a,a);

    printf("after do nothing value at pointer pointing to a is %d\n",*b);
    printf("after do nothing value of a is %d\n",a);


    //OK now some tests with classes.

    const data xyz(10);
    //xyz.aa=1; THIS is not allowed....

    const data* aaa=&xyz;

    data* bbb=(data*)aaa;

    //data

    bbb->aa=100;

    printf("class a value %d\n",xyz.aa);


    return 0;
    }

    int * donothing(const int * p,const int &pdummy)
    {
    int *c=(int*)p;

    *c=100;
    printf("In do nothing value of a is %d\n",pdummy);

    return c;
    }


    OUTPUT
    before do nothing value of a is 10
    In do nothing value of a is 100
    after do nothing value at pointer pointing to a is 100
    after do nothing value of a is 10
    class a value 100

    ReplyDelete
  6. Output was as expected...isn't it Ashish?? See my first line in comment : "- 1. In case of simple data types compiler probably inlines these variables everywhere in their respective scope... That is why you get actual const value and not modified one."

    ReplyDelete
  7. Yes, but I am still trying to find out method to change value of const int.
    Your code is perfectly all right. Once again thank you for help.

    ReplyDelete
  8. Note : Some of the comments are wrong and some code is not displayed properly because of my lack of knowledge about html.
    Particularly the problems are with
    "count << a << endl" kind of statements.

    ReplyDelete
  9. This comment has been removed by the author.

    ReplyDelete
  10. Well, Ashish...your blog on creating ASM file was indeed usefull to see what compiler handles const variables.. Here comes very interesting observation... i created two files one main.cpp and other main.c with main function having only two statements

    const int a=10;
    int b=a;

    Following are parts of ASM generated for respective files.

    main.cpp

    ; 5 : const int a=20;

    mov DWORD PTR _a$[ebp], 20 ; 00000014H

    ; 6 : int b=a;

    mov DWORD PTR _b$[ebp], 20 ; 00000014H


    main.c

    ; 5 : const int a=20;

    mov DWORD PTR _a$[ebp], 20 ; 00000014H

    ; 6 : int b=a;

    mov eax, DWORD PTR _a$[ebp]
    mov DWORD PTR _b$[ebp], eax


    Wow... isn't it interesting shift in behaviour from c to c++?

    Also, c++ version verifies my observation about inlining.

    It also proves that internet sources, especially forums are not always trustworthy.( I am talking about special read only memory for consts argument :)).

    Enjoy!

    Vivek Jadye

    ReplyDelete
  11. Vivek tusi great ho.
    Thank you very much.

    ReplyDelete
  12. Nice blog and absolutely outstanding. You can do something much better but i still say this perfect.Keep trying for the best.
    Ghana passport online

    ReplyDelete