Const variable changed with pointer in C

The variable i declared as const, but still I can change the value with a pointer to a memory location. How is this 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 

The way out is

 100 100 
+4
source share
5 answers

const is a compile-time function.
This does not stop you from shooting in the leg; what a warning.

+8
source

const not a compiler request to make it impossible to change this variable. Rather, it is a promise to the compiler that you will not. If you break your promise, your program can do something at all, including a failure.

For example, if I compile the sample code using gcc with an optimization level of -O2 , the output will be as follows:

 100 11 

The compiler is allowed to put a qualified const variable into read-only memory, but it is not required (among other things, some environments do not implement such a thing). In particular, it is almost always impractical for automatic ("local") variables to be placed in read-only memory.

If you change declaration i to:

 static const int i = 11; 

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

+8
source

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

If you can somehow use this const int in C / C ++, this can lead to undefined behavior . The reason is because you are executing a literal number (i.e. const int i = 11 ; ) from const to mutable value.

There is a difference between the code shown and the following sequence:

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

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 that is not declared as const can be modified, but not using const -qualified lvalues. This is most obvious when it comes to pointers. For example, consider ads:

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

You can change i through i and through p1 , but not through p2 . This means that *p2 can evaluate different values, even if p2 points to a const object, since other operators can change the object pointed to by p2 (smoothing pointer, as in the example).

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

+2
source

This is not an attempt to change i , which leads to the fact that the behavior of your program will be undefined, this is the initialization of ip .

 const int i = 11; int *ip = &i; 

&i is of type const int* . ip is of type int* . Attempting to initialize int* const int* is a violation of the constraint. An appropriate implementation requires diagnostics; as soon as he does, he may or may not reject the translation block. If it accepts this, the C standard says nothing about the resulting behavior of the program.

Compilers that accept such things usually generate code equivalent to converting from const int* to int* , which makes the declaration virtually equivalent:

 int *ip = (int*)&i; 

but language does not require such behavior.

Do not ignore warnings.

(Note that with cast code does not violate the restriction, and then the behavior of the following

 *ip = 100; 

is undefined because it is trying to modify the const -qualified object.)

In particular, gcc has many cases in which the diagnosis of constraint violations is treated (by default) as warnings rather than fatal errors. I personally don't like this in gcc; it misses too much bad code.

(The behavior of your program is also undefined, because you call printf without a visible declaration, add #include <stdio.h> . And int main() should be int main(void) .)

0
source

Source: https://habr.com/ru/post/1397541/


All Articles