Changing a const parameter

Dear all,

I was trying to cheat the compiler a bit, changing the value of a const parameter. Like this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <iostream>
using namespace std;


//const int m = 0; // Here.
int main()
{
	const int m = 0;
	int n = 1;
	int* p;
	int k = &m - &n;
	p = &n + k;
	*p = 1;
	cout << *p << endl;
	cout << m << endl; 
        return 0;
}

Which gives:
1
2
1
0

It didn't succeed because I guess m was put to the commands as inline values at compiling time. But the point is that we can change the value at the address m (useless anyway.)

What I don't understand is that if I declare the variable m out side the main function like in the comment line (// Here.), the a.out cracks because of segmentation fault, or stopped by Windows at runtime. So what is the difference between declaring a variable outside and inside the main function? What is the benefit of the space outside functions actually?

Wish to hear your comments, thank you, in advance.
Last edited on
So what is the difference between declaring a variable outside and inside the main function?
Inside it's on the stack. Outside it's on the heap. Outside - Inside = trying to walk through the wall = segmentation fault
try this:

#include <iostream>
using namespace std;


1
2
3
4
5
6
7
8
9
10
11
12
13
14
const int m = 0; // Here.

int main()
{
	const int m = 0;
	const_cast<int>(n) = 1;
	int* p;
	int k = &m - &n;
	p = const_cast<int>(&n) + k;
	const_cast<int*>(p) = 1;
	cout << *p << endl;
	cout << m << endl; 
        return 0;
}


const_cast <type>(const variable) should temporaly remove const;
varible will still be const!
not shure when using pointers.. try out :)
You are asking why you can assign values to const variables, but they don't show up when queried. And why it does not "work" on global scope.

Well, actually it does not work on either scope - global or local. What you do is "undefined behaviour" and this means that the programm can do what it wants, including crashing and doing weird things like ignoring your variables.

The problem is, that the variable was declared const in the first place, so you got a real and true const variable. And for that, you are just not allowed to change its value, period. ;)

You can use const_cast (or any normal old-style C-cast) to remove the const specifyer to trick your compiler into believing it is a non-const variable, but you are still not allowed to change the memory behind the variable. The compiler gets this as guarantee from the C++ standard and usually use this guarantee to optimize code.

For example, the compiler may put the memory location of the variable into some read-only data segment (or even in the code segment). The operating system will then enforce, that nothing writes on these memory pages and rather kill the process by a segfault then allowing the write operation.

As you have already seen, the compiler even can remove the variable completely from the binary (except if you attempt to get its address - in this case the compiler generates some dummy place. But still he can give you any address, including pointers to some read-only memory pages.)

Here an example where you can use const_cast and where not:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
int m = 0; // not declared const!
const int mconst = 1;

int main()
{
    const int* p = &m; // const pointer to a non-const variable
    int* i = const_cast<int*>(p); // remove the const again.
    *i = 42; // writing to the variable. This is ONLY possible, if m was never declared const in the first place

    // possible, as long as you never ever write to the location i2 is pointing to
    int* i2 = const_cast<int*>(&mconst);

    // *i2 = 23;   <-- don't do this! You are not allowed to write to const-memory locations.
}

Last edited on
Global variables and local variables are different if both declared. For example..
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
const int m = 1;
int myFunc();

int main()
{
     cout << m << endl; //Will write 1 to console
     myFunc();
     cout << m << endl; //Will write 1 to console
return 0;
}

int myFunc()
{
     const int m = 5; //Declares a local variable 'm' which in turn IGNORES the global 'm'
     cout << m << endl; //Will write 5 to console
}


Understand? I literally JUST learned about this in my book. :D Basically when you declare a global variable, then by default every function will use this variable. However, if you declare a new variable with the same name WITHIN the function, then it is localized and the global variable is completely ignored. Once the program is out of that function, then it goes back to using the global variable with no changes whatsoever to whatever happened to the local variable.
Last edited on
Hi Noobie, thanks for reminding me that I read that once :-P But I also wonder that if the global variables are somehow "more protected or not", or how the memory is organized. If you compare the program in C++ with pascal or fortran, then the others have a main program (not function), all the others are functions, which are called by the program. In C++ you have "main function", but it is also a function anyway. I also want to see what is the benefit of having "main function", instead of a "main program."

Regarding that point is the comment of coder777, but would you please explain a bit what do you mean by "trying to walk through the wall"? I still can access to the variables , like in example of TheNoobie. Thanks.

Thank imi and sasanet, I am still thinking about your comments (actually I don't have the desire for the odd action - changing the value of a const, just wanna understand things behind the code.)

For example, the compiler may put the memory location of the variable into some read-only data segment (or even in the code segment). The operating system will then enforce, that nothing writes on these memory pages and rather kill the process by a segfault then allowing the write operation.

Maybe I misunderstand your point. But I thought the compiler really puts the memory address of "m", could it be any address? The reason is: you still can refer to that pointer with reading m correctly.



Topic archived. No new replies allowed.