Const variable changed with pointer in C

The variable i is declared const but still I am able to change the value with a pointer to the memory location to it. How is it possible?

int main()
{

    const int i = 11;
    int *ip = &i;
    *ip=100;
    printf("%d\n",*ip);
    printf("%d\n",i);
}

When I compile, I get this warning :

test.c: In function ‘main’:
test.c:11: warning: initialization discards qualifiers from pointer target type

Output is this

100
100

Solution 1:

const is a compile-time feature.
It doesn't prevent you from shooting yourself in the foot; that's what the warning is for.

Solution 2:

The const is not a request to the compiler to make it impossible to change that variable. Rather, it is a promise to the compiler that you won't. If you break your promise, your program is allowed to do anything at all, including crash.

For example, if I compile your example code using gcc with the -O2 optimisation level, the output is:

100
11

The compiler is allowed to place a const qualified variable in read-only memory, but it doesn't have to (apart from anything else, some environments don't implement any such thing). In particular, it is almost always impractical for automatic ("local") variables to be placed in read-only memory.

If you change the declaration of of i to:

static const int i = 11;

then you may well find that the program now crashes at runtime.

Solution 3:

Though it may be a warning in C, this is a compiler error in C++.

If you somehow manage to cast this const int in C/C++, then it may result in undefined behavior. The reason is, you are casting a number literal (i.e. const int i =11;) from const to a mutable value.

There is difference between what your code shows and following sequence:

int x = 11;    // x is modifiable
const int i = x;
int *ip = (int*)(&i);  // ok
*ip=100;

Solution 4:

A const-qualified object cannot be modified. If such an attempt is made, the program exhibits undefined behavior (C99 6.7.3.5). (Your program is incorrect.)

More on const: an object which is not declared as const can be modified, but not by the use of const-qualified lvalues. This is most evident when pointers are involved. For example, consider the declarations:

int i = 10;
int *p1 = &i;
const int *p2 = &i;

It is possible to modify i through i itself and through p1, but not through p2. This means that *p2 can evaluate to different values, even though p2 points to a const object, because other statements may change the object pointed to by p2 (an aliasing pointer, as in the example).

However, if i itself was const-qualified, then attempting to modify it through p1 will yield undefined behavior (as your code does).