In C, can a const variable be modified with a pointer?

I wrote something similar to this in my code

const int x=1; int *ptr; ptr = &x; *ptr = 2; 

Does this work on all compilers? Why doesn't the GCC compiler notice that we are changing a constant variable?

+4
source share
4 answers

const does not actually mean "constant." That a "constant" in C has a value defined at compile time; an example is literal 42 . The const keyword really means read only. Consider, for example:

 const int r = rand(); 

The value of r not determined until the execution time of the program, but the const keyword means that you are not allowed to change r after it is initialized.

In your code:

 const int x=1; int *ptr; ptr = &x; *ptr = 2; 

assignment ptr = &x; is a violation of the restriction, which means that the corresponding compiler must complain about it; you cannot legally assign the value const int* (a pointer to const int) to a non-const int* object. If the compiler generates an executable file (which it does not need to do, it can simply reject it), then the behavior is not defined by the C standard.

For example, the generated code can actually store the value 2 in x - but then a later reference to x can give the value 1 , because the compiler knows that x can't be changed after it was initialized. And he knows that, as you said so, defining x as const . If you lie to the compiler, the consequences can be arbitrary.

Actually, the worst thing that can happen is that the program behaves the way you expect; this means that you have a mistake that is very difficult to detect. (But the diagnosis you should have received was a great clue.)

+9
source

Online Project C 2011 :

6.7.3 Typical qualifiers

...
6 If an attempt is made to modify an object defined using the const-quali-fi type using an lvalue with a non-constant qualification type, the behavior is undefined . If an attempt is made to access an object defined with variable quality using an lvalue value with a non-qualification type, the behavior is undefined. 133)
133) This applies to those objects that behave as if they were defined using qualified types, even if they were never actually defined as objects in the program (for example, an object at the input / output with a memory address).

Accent added.

Since the behavior remains undefined, the compiler is not required to issue diagnostics, and there is no need to stop the translation. It would be difficult to catch in the general case; suppose you have a function like

 void foo( int *p ) { *p = ...; } 

defined in it by its own separate translation unit. During translation, the compiler does not know if p point to a const -qualified object or not. If your call is like

 const int x; foo( &x ); 

you might get a warning like parameter 1 of 'foo' discards qualifiers or something like that.

Also note that the const qualifier does not necessarily mean that the associated variable will be stored in constant memory, so it is possible that the above code "works" (updates the value in x ) in this you successfully updated x by completing the end of the const semantics. But then you can simply not declare x as const .

+3
source

Bad programmer. No moon cake!

If you need to change a constant, copy it to a non-constant variable and then do it. This is for some reason. Trying to sneak around const can lead to serious runtime problems. that is, the optimizer most likely used the inline value, etc.

 const int x=1; int non_const_x = x; non_const_x = 2; 
0
source

There is a good discussion of this question here: Does an evil compiler turn into an evil compiler?

I would expect gcc to compile this because:

  • ptr is allowed to point to x, otherwise reading would not be possible, although the comment below says that this is not really brilliant code, and the compiler should complain. The warning options will (I think) affect whether it was actually warned.
  • when you write x, the compiler no longer "knows" what it writes to const, all this is in the hands of coders in C. However, it really knows, so it can warn you, depending on which you choose.

Whether it works or not depends on how the code is compiled, how the const method is implemented for the selected compilation options and the target CPU and architecture. It might work. Or he may fall. Or you can write a β€œrandom” bit of memory and cause (or not) some kind of bizarre effect. This is not a good coding strategy, but that was not your question :-)

-1
source

All Articles