Jump to content
  • Advertisement
Sign in to follow this  
aeroz

Same address with different values??

This topic is 2921 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I was experimenting with the c-style cast "()" and found a very strange behavior I can't understand:

#include <iostream>
using namespace std;

int main() {
const int i=5;
int* p = (int*)&i;
*p = 3;
cout << "i = " << i << endl
<< "*p = " << *p << endl
<< "&i = " << &i << endl
<< "p = " << p << endl;
return 0;
}


This produces the output

i  = 5
*p = 3
&i = 0x7fffd9d9cccc
p = 0x7fffd9d9cccc


This was compiled with g++ 4.4.3

How is it possible that the values in the same address are different?

Share this post


Link to post
Share on other sites
Advertisement
Quote:
Original post by aeroz
How is it possible that the values in the same address are different?


Because the behaviour is undefined. Anything may happen. That's as far as you ought to be thinking about it in normal circumstances. There is no point in trying to figure out what a compiler did when you allowed it to do literally anything, because there isn't even a guarantee that it will do the same thing in the same situation next time.

Share this post


Link to post
Share on other sites
Your cast to remove the const qualifier on i and then attempt to change it is undefined behavior, so from that point on, all bets are off and anything could happen. And anything is actually what's happening; printing 5 and 3 for what appear to be the same variable.

In practice though, since you reference i by pointer, there's probably some space for it somewhere so you can point to it. That's why you can modify it to 3 and print it through the pointer. However, since it's a compile time constant, its value is allowed to be replaced throughout the program, which is why i still evaluates to 5. However, as said above, once you remove the const qualifier, you're in the land of undefined behavior.

Share this post


Link to post
Share on other sites
Thanks for the info.

Your explanations with the replacements makes sense!

The expression
cout << *(int*)((long)&i);
prints in fact the real value of i (3)


I thought const was only there to prevent programmers from changing the value of a variable. Now I now that it is more than that... Thx

Share this post


Link to post
Share on other sites
Quote:

I thought const was only there to prevent programmers from changing the value of a variable...

This is correct. However, it is a bit stronger than you initially believed.

Const has two meanings. Applied to a pointer or reference, it means that access through this pointer or reference cannot change the value. However, consider the following function:

void example(const int &readOnly, int &readWrite)
{
std::cout << "Read Only: " << readOnly << '\n';
readWrite = 42;
std::cout << "Read Only: " << readOnly << '\n';
}


What happens if the user calls this function like so:

int main()
{
int x = 0;
example(x, x);
}


The "read-only" value can change, this is perfectly well defined behaviour.

When you declare a variable const, that is different. You are promising the compiler that you won't ever modify the variable anywhere, even if the variable is accessed through a pointer or reference where the const has been casted away.

In most cases, const variables can be optimised away. However, if you obtain a pointer to them, the compiler will allocate some memory for them. On some systems, this might be read-only memory. On others, it might be read-write. Writing to that value is undefined.
Quote:

The expression
cout << *(int*)((long)&i);
prints in fact the real value of i (3)

Variables don't have a "real value". The compiler can and will transform the code into something that doesn't even use variables. Values might be removed, hard coded, evaluated at compile time or kept in registers. The compiler is allowed to do a wide variety of optimisations that do not affect the apparent behaviour of the program. This only works when your entire program is well defined. Any instances of undefined behaviour can and typically will result in the apparent behaviour differing from the "expected behaviour" (which is often subjective anyway).

Share this post


Link to post
Share on other sites
Quote:
Original post by rip-off
Const has two meanings. Applied to a pointer or reference, it means that access through this pointer or reference cannot change the value. However, consider the following function:
*** Source Snippet Removed ***
What happens if the user calls this function like so:
*** Source Snippet Removed ***
The "read-only" value can change, this is perfectly well defined behaviour.

This is a good example that shows that you should be careful using const...
Quote:
Original post by rip-off
Variables don't have a "real value". The compiler can and will transform the code into something that doesn't even use variables. Values might be removed, hard coded, evaluated at compile time or kept in registers. The compiler is allowed to do a wide variety of optimisations that do not affect the apparent behaviour of the program. This only works when your entire program is well defined. Any instances of undefined behaviour can and typically will result in the apparent behaviour differing from the "expected behaviour" (which is often subjective anyway).

Yeah, you are right!

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!