in main () wrote the following

int const a=10; int *p=(int*)(&a); *p=20; cout<< a << endl; cout<< *p << endl; return 0; 

In the debugger, I observe a change in the value of the variable "a" from 10 to 20. But 10 and 20 are displayed on the screen. That is, although I clearly changed the constant variable (I know that you can’t do this, I just tested it) the previous value was displayed. Run under Windows and under ubuntu on a virtual machine. Why is it that 10 20 is displayed instead of 20 20?

  • 2
    Because the compiler can optimize the constant and reference to it. Compile the code with different levels of optimization, and even better - compare the assembly listings - gecube

3 answers 3

The compiler sees that a is a constant. It means that she cannot change (he has the right to count on it). Accordingly, when he sees the output of the variable a - he has the legal right to substitute a ready-made known value. That is, the compiler converts it to such

 int const a=10; int *p=(int*)(&a); *p=20; cout<< 10 << endl; cout<< *p << endl; return 0; 

And as long as the variable does not change, the value will still be displayed not what you expect.

    The compiler "knows" that a does not change, and therefore displays the original value.

    Add the volatile attribute (it says that the memory value can change regardless of the code generated by the compiler) and see:

     volatile int const a=10; int *p=(int*)(&a); *p=20; cout<< a << endl; cout<< *p << endl; return 0; 

    Now

     avp@wubu:hashcode$ g++ tt.cpp && ./a.out 20 20 avp@wubu:hashcode$ 
    • 2
      I can ask a garbage, but how does the compiler generally perceive volatile const ? Those. constant which is not constant? .. - pavel
    • one
      @pavel, it turns out that way. Yet volatile is sometimes vital, and const by and large for fans of abstractions. Probably, the compiler (at least with the -pedantic -Wall -Wextra ) in such a situation would be worth withdrawing the warning, but apparently "the hands did not reach." - avp
    • one
      const is a good thing - it helps to tell the compiler about optimizations and expectations. But in the example above, it is difficult for the compiler to understand what the constant is changing there. Although yes, he could have guessed in this particular example, but it is possible to fiddle such arithmetic with something that the compiler will not make out in a year. - KoVadim
    • one
      @KoVadim, of course, although in principle, const , unlike volatile , we calculate. Obviously, therefore, volatile has more weight. - avp
    • With the mass turned out without volatile - Anton

    With an array rolled without volatile. changed and displayed the changed value

     const int arr[2][2]={{1,2},{3,4}}; int *p=(int *)((arr[1]+1)); cout<<"before"<<endl; cout<<"*p = "<<*p<<endl; cout<<"arr[1][1] = "<<arr[1][1]<<endl; cout<<"after"<<endl; *p=60; cout<<"*p = "<<*p<<endl; cout<<"arr[1][1] = "<<arr[1][1]<<endl; return 0; 
    • C ++ has many ways to trick the compiler. And a lot of ways to shoot yourself. But is it necessary to do this? Always remember the simple thing - do not try to deceive the compiler, otherwise it will understand it and punish. - KoVadim