6

I am able to change the value of const modified variable in gcc but not in other compilers. I have tried this code on gcc, which updates the value of i and j (11). With an online compiler, I get different values.

#include<stdio.h>
void main() {
  const int i=10;
  int *j;
  j = &i;
  (*j)++;
  printf("address of j is %p address of i is %p\n",j,&i);
  printf("i is %d and j is %d\n",i,*j);
}
Sibidharan
  • 2,717
  • 2
  • 26
  • 54
user1412970
  • 85
  • 1
  • 1
  • 4
  • is that the actual code? IIRC 'j = &i' shouldn't actually compile. – Tom Tanner Aug 24 '12 at 07:33
  • 2
    @TomTanner: It's a constraint violation, requiring a diagnostic. A non-fatal warning is good enough as far as the standard is concerned. – Keith Thompson Aug 24 '12 at 07:38
  • 4
    This is the same thing as asking "I bought a one-way ticket, how do I use that ticket to get back home?". Call any airline company and ask that question, then you will get an answer that also applies to your programming question. – Lundin Aug 24 '12 at 08:21
  • 1
    @Lundin: Great. Another company who blacklisted me. Thanks! – bitmask Aug 24 '12 at 14:56
  • 1
    `-pedantic-errors` and gcc won't let you compile things for which the standard demand a diagnostic, `void main` included. – AProgrammer Aug 24 '12 at 15:10
  • @AProgrammer: It's true that `gcc -pedantic-errors` rejects `void main`, but the standard doesn't require a diagnostic for `void main`. It's undefined behavior, not a constraint violation. – Keith Thompson Sep 21 '15 at 22:19
  • @Lundin: I currently need to modify a const variable, and it is the same thing as asking "I bought a one-way ticket, but actually a return ticket, yet I am at the source end, how do I use that ticket to first get to the destination end". The airline company will probably ask to buy another ticket, which in this case may be to use pointers. For my case, all I want is to initialise the value of a global const variable at runtime with the result from malloc(large amount). – yemelitc Nov 16 '16 at 03:17
  • Using pointers to access a read-only variable and cast away const is not "to buy another ticket", but rather to break into the airport, sneak out on the runway and try to jump on any plane as it accelerates for lift-off, hoping you won't die horrible while doing so, at the same time hoping that the random plane you tried to jump on actually goes where you want to go. – Lundin Nov 16 '16 at 07:30
  • "to initialise the value of a global const variable at runtime with the result from malloc(large amount)" is however nonsense. If you know how much memory you need to allocate at compile time, then there is no need to use malloc. You have to realize that artificial requirements such as these only originate from lack of knowledge, experience and program design. – Lundin Nov 16 '16 at 07:32

5 Answers5

20

Yes, you can do it with a little hack.

#include <stdio.h>
int main(){
    const int a = 0;
    *(int *)&a = 39;
    printf("%d", a);
}

In the above code, a is a const int. With the little hack, you can change the constant value.

Update: Explanation

In the above code, a is defined as a const. For example a has a memory addr 0x01 and therefore &a returns the same. When it is casted with (int *) it becomes another variable referred as a pointer to the const. When it is accessed with * again, the another variable can be accessed without violation of the const policy because it is not the original variable, but the changes are reflected because it is referred as address to the pointer.

This will work on older versions like Borland C++ or Turbo C++, however no one is using it now a days.

It's "undefined behaviour", meaning that based on the standard you can't predict what will happen when you try this. It may do different things depending on the particular machine, compiler, and state of the program.

In this case, what will most often happen is that the answer will be "yes". A variable, const or not, is just a location in memory, and you can break the rules of const and simply overwrite it. (Of course this will cause a severe bug if some other part of the program is depending on its const data being constant!)

However in some cases -- most typically for const static data -- the compiler may put such variables in a read-only region of memory. MSVC, for example, usually puts const static ints in .text segment of the executable, which means that the operating system will throw a protection fault if you try to write to it, and the program will crash.

In some other combination of compiler and machine, something entirely different may happen. The one thing you can predict for sure is that this pattern will annoy whoever has to read your code.

Try this and let me know.

Sibidharan
  • 2,717
  • 2
  • 26
  • 54
9

How to modify value of const variable?

No! You shouldn't modify a const variable.
The whole point of having a const variable is to be not able to modify it. If you want a variable which you should be able to modify, simply don't add a const qualifier on it.

Any code which modify's a const forcibly through (pointer)hackery invokes Undefined Behavior.

An Undefined Behavior means that the code is non conforming to the standard specifications laid out by the C standard and hence not a valid code. Such a code can show any behavior and it is allowed to do so.

Community
  • 1
  • 1
Alok Save
  • 202,538
  • 53
  • 430
  • 533
  • 2
    Absolutely! Never change a const variable. On some embedded systems, const variables are stored on flash instead of RAM, so it just can NOT be changed. – Mine Aug 24 '12 at 07:34
  • 4
    `const int r = rand();` won't be stored in flash. `const` doesn't mean "constant", it means "read-only". – Keith Thompson Aug 24 '12 at 07:37
  • True, what you said in most cases, especially in high level languages. but when working on low level / embedded systems where you are really constrained with memory (RAM), you better save big chunk Array in flash and copy in RAM when needed. In such corner cases, pointer hackery method is a big savior to save RAM for most other important calculations. – Khulja Sim Sim Mar 04 '14 at 22:35
  • Downvoted, won't answer the question. – YoTengoUnLCD Jul 08 '16 at 14:15
  • 1
    @YoTengoUnLCD : The answer is it is UB and it can show any behavior, that is what the answer says. What in your opinion would answer the question? – Alok Save Jul 08 '16 at 14:46
  • @AlokSave Actually showing how to modify the variable would answer the question. Having UB as a consequence doesn't answer it. – YoTengoUnLCD Sep 18 '16 at 22:23
  • 2
    @YoTengoUnLCD It does not serve any purpose to tell someone how to write a invalid code. Explaining them why it should not be done does serve a purpose. This can have an analogy to, if a person asks how to jump from a bridge, you don't tell them how to, you tell them if u do you will die so to drop the idea. – Alok Save Sep 19 '16 at 00:56
  • @YoTengoUnLCD: I think UB is a valid answer. Say I have a bit, certain to be either a 0 or a 1, not both nor neither. But there is no way to tell which state, and so is said to be undefined. Certainly if I measure I will know. But for that I have to interact with the system - that is bound to bias the result. So in the end the result does not tell the state of the bit but the state as per the measurement’s point of view. The state remains undefined. My point is: the only way to tell the state is to define it, not measure it (a bit like Quantum vs Classical Physics). A defined answer can be UB. – yemelitc Nov 16 '16 at 04:02
7

By defining i as const, you promised not to modify it. The compiler can rely on that promise and assume that it's not modified. When you print the value of i, the compiler can just print 10 rather than loading whatever value is currently stored in i.

Or it can choose to load the value. Or it can cause your program to crash when you try to modify i. The behavior is undefined.

You'll likely see different behavior with gcc depending on the optimization options (-O1, -O3).

Oh, and void main() is incorrect; it should be int main(void). If your textbook tells you to use void main(), you should get a better book.

Keith Thompson
  • 254,901
  • 44
  • 429
  • 631
2

Take a look at Can we change the value of an object defined with const through pointers?

Long story short, it's an undefined behaviour. It can result dependently on compiler/machine.

Community
  • 1
  • 1
Seçkin Savaşçı
  • 3,446
  • 2
  • 23
  • 39
0

You can not modify the value of const variable if you compile this code in gcc it will show

error: invalid conversion from ‘const int*’ to ‘int*’ [-fpermissive]

and show undefined behave

The maiin thing is that we can only modify the variable when we can access the address without address we can't do anything. That's the same thing with Register storage class.

Varun Chhangani
  • 1,116
  • 3
  • 13
  • 18