1

The below code:

#include<iostream>

using namespace std;

int main(){
    const int x = 2;
    cout << "&x: " << &x << ", x: " << x << endl;

    int *a = &x;
    *a = 16;
    cout << "a: " << a << ", *a: " << *a << ", x: " << x << ", &x: " << &x << endl;

    int* p = a;
    cout << "p: " << p << ", *p: " << *p << ", x: " << x << ", &x: " << &x << endl;
    *p = 15;
    cout << "*p: " << *p << ", x: " << x << ", &x: " << &x << endl;

}

It produces below output on compiling with -fpermissive:

$ g++ const.cpp  -fpermissive
const.cpp: In function ‘int main()’:
const.cpp:8:15: warning: invalid conversion from ‘const int*’ to ‘int*’ [-fpermissive]
     int *a = &x;
               ^


$ ./a.out 

&x: 0x7ffeead2042c, x: 2
a: 0x7ffeead2042c, *a: 16, x: 2, &x: 0x7ffeead2042c
p: 0x7ffeead2042c, *p: 16, x: 2, &x: 0x7ffeead2042c
*p: 15, x: 2, &x: 0x7ffeead2042c

This seems completely un-intuitional. How can the same address have two different values? Both a and &x have same address. But *a and x have different values. How is that possible? PS: It works as expected when I don't use const in the declaration of x.

  • 3
    It's completely intuitive; `const int x = 2;` says that the value of `x` will never change, and the compiler trusted you and used 2 directly when it could, because it knew what the value was going to be. When you lie, don't be surprised if strange things happen. – molbdnilo Sep 14 '22 at 13:35
  • 2
    As the warning states, you are not allowed to do `int *a = &x;`. It allows `*a = 16;` which modifies a constant, which is Undefined Behavior. The result of running this code is therefore meaningless. Don't use `-fpermissive`, you want the least permissive options to help reduce the number of bugs in your code. – François Andrieux Sep 14 '22 at 13:35
  • 1
    You have Undefined Behaviour, any observation you made cannot be reasoned. `const` variable may not be modified under any circumstances. Possibly compiler optimized print calls and replaced `x` with `2` directly (since it knows `x` cannot change throughout the program, it can do that). – Yksisarvinen Sep 14 '22 at 13:36
  • 1
    *"Undefined behavior means anything can happen including but not limited to the program giving your expected output. But never rely on the output of a program that has UB. The program may just crash"*. Also, refer to [how to ask](https://stackoverflow.com/help/how-to-ask) where the first step is to *"search and then research"* and you'll find plenty of related SO posts for this. – Jason Sep 14 '22 at 13:40
  • 2
    C++ is not a nanny language. The compiler trusts that the programmer knows what's being done. If the programmer lies to the compiler, the compiler doesn't know its being fooled, and will do foolish things based on the misinformation. C++ gives you enough rope to shoot yourself in the foot. The upshot is: don't lie to the compiler. Enable all the compiler warnings you can. Fix all the compiler warnings. Consider using code sanitizers. – Eljay Sep 14 '22 at 14:02
  • Thanks for the helpful comments. I understood the issue. I was expecting compiler to not-allow undefined behaviour (and throw compile time error) but looks like -fpermissive tells the compiler to allow it (with a warning sign). – nullptrexception Sep 15 '22 at 04:40

0 Answers0