views:

356

answers:

5

I wanted to change value of a constant by using pointers.

Consider the following code

int main()
{
    const int const_val = 10;
    int *ptr_to_const = &const_val;

    printf("Value of constant is %d",const_val);
    *ptr_to_const = 20;
    printf("Value of constant is %d",const_val);
    return 0;
}

As expected the value of constant is modified.

but when I tried the same code with a global constant, I am getting following run time error. The Windows crash reporter is opening. The executable is halting after printing the first printf statement in this statement "*ptr_to_const = 20;"

Consider the following code

const int const_val = 10;
int main()
{
    int *ptr_to_const = &const_val;
    printf("Value of constant is %d",const_val);
    *ptr_to_const = 20;
    printf("Value of constant is %d",const_val);
    return 0;
}

This program is compiled in mingw environment with codeblocks IDE.

Can anyone explain what is going on?

+12  A: 

It's a constant and you are using some tricks to change it anyway, so undefined behavior results. The global constant is probably in read-only memory and therefore cannot be modified. When you try to do that you get a runtime error.

The constant local variable is created on the stack, which can be modified. So you get away with changing the constant in this case, but it might still lead to strange things. For example the compiler could have used the value of the constant in various places instead of the constant itself, so that "changing the constant" doesn't show any effect in these places.

sth
+4  A: 

Casting away pointer const-ness in C and C++ is only safe if you are certain that the pointed-to variable was originally non-const (and you just happen to have a const pointer to it). Otherwise, it is undefined, and depending on your compiler, the phase of the moon, etc, the first example could very well fail as well.

Tyler McHenry
+2  A: 

You should not even expect the value to be modified at the first place. According to the standard, it is undefined behavior. It is wrong both with a global variable and in the first place. Just don't do it :) It could have crashed the other way, or with both local and global.

Jem
A: 

Since this behavior is not defined in the specification, it is implementation-specific, so not portable, so not a good idea.

Why would you want to change the value of a constant?

Buggieboy
It is for testing a part of code controlled by constant
udpsunil
@udpsunil: it might be a good idea to use some macros which can be defined as needed for such testing purposes
Christoph
+3  A: 

It's in read only memory!

Basically, your computer resolves virtual to physical addresses using a two level page table system. Along with that grand data structure comes a special bit representing whether or not a page is readable. This is helpful, because user processes probably shouldn't be over writing their own assembly (although self-modifying code is kind of cool). Of course, they probably also shouldn't be over writing their own constant variables.

You can't put a "const" function-level variable into read only memory, because it lives in the stack, where it MUST be on a read-write page. However, the compiler/linker sees your const, and does you a favor by putting it in read only memory (it's constant). Obviously, overwriting that will cause all kinds of unhappiness for the kernel who will take out that anger on the process by terminating it.

Alex Gartrell