Click here to Skip to main content
15,891,607 members
Please Sign up or sign in to vote.
5.00/5 (1 vote)
See more:
Q) How one address can store tho values of same data type.

The code is as follows:
C++
//Programe
#include<iostream>
void main()
{
    const int x = 10;
    int *p=(int*)&x;

    *p=20;

    std::cout<<"*p="<<*p<<"  p="<<p<<std::endl;
    std::cout<<" x="<<x<<" &x="<<&x<<std::endl;
}

//Output
*p=20 p=0013FF60
x=10 &x=0013FF60
Press any key to continue . . .

//S/W details
Visual Studio 2008
ver. 9.0

I am flumoxed that how can one address have two values. !!!
Any help is appricated.
Posted
Updated 17-Sep-10 23:13pm
v2

Hmm, an interesting one!
Because x is declared as const int the compiler treats it the same as #define x 10 and replaces every 'x' in the source code with the value 10. However it appears that a variable called x still exists and can be modified as you demonstrate. Generating the assembly code from the compiler confirms this.

No doubt someone who understands the C++ specification may be able to clarify this.
 
Share this answer
 
Comments
Eugen Podsypalnikov 18-Sep-10 14:55pm    
It's correctly, the "cout << x" is "precompilled",
but the debugger shows the modified value of x... :)
See also:
const int iSize(3);
int iSize2(3);
int ai[iSize]; // OK
int ai2[iSize2]; // error C2057: expected constant expression
The problem you've got is that you're doing something that's undefined in the language. When you declare a const anything you're saying to the compiler "I'm not going to modify this." As soon as you do something that might modify it through pointer chicanery all bets are off and you're into the teritory of.... drum roll.... undefined behaviour.

So when you take the address or a reference to a const object and then try and write through it just about anything can happen. Remember that when you do a cast you're telling the compiler you know better and it should do what you tell it. This is the compiler getting it's revenge and telling you "Ah ha foolish C programmer [1], you have entered the domain of Bjarne, feel his mockery!!"

C++ isn't like C. When you create a const in C you're saying "make a variable but make it read only." In C++ you're saying "This name is an alias for that value." Taking the address of a constant is different as well. In C you're saying "give me the address of that variable, I want to read from it through a level of indirection." In C++ you're saying "I want to use that value as if it were a real readonly variable" (usually for a function call) and the compiler obliges. It creates a temporary of the right type and gives you it's address. So while casting away const on a const variable might work in C it's undefined (i.e. bad) when you do it in C++.

To put that in C terms what you're doing is:

const int x = 10;

int y = x;
int *p = &y;


Except you never see y.

Incidentally had you done something like:

C#
void set_to_20( const int *p )
{
    *const_cast<int *>( p ) = 20;
}

int main()
{
    const int x = 10;
    int y = 10;

    set_to_20( &x );
    set_to_20( &y );

    std::cout << x << '\t' << &x << std::endl;
    std::cout << y << '\t' << &y << std::endl;
}


you'll see that you can safely cast away const from &y as it refers to a non-const int but not from &x as there is no variable called x to write to.

Now you know what's going on with Microsoft's compiler, don't rely on it. While MS use a fairly orthodox way of interpreting the standard here but there are other things that a compiler might do that could sink you without a trace. One is (for example) sticking the temporary in read only memory and crashing your code when it tries to write.

Er, anyway. That's me whittering on enough. Ooo, couple of more points...

- main returns an int in both C and C++. If it doesn't then anything can happen. Returning void is only good for being mocked by programmers that want to write standard code that compiles on more than one compiler, it has no other utility.

- (int *) is so 1990s - consider what you want your cast to do and use either static_cast (converting compatible values), reinterpret_cast (fitting the bits into a new mould) or const_cast (removing const or volatile).

Cheers,

Ash

[1] Don't deny it, taking addresses of consts and using C style casts are a dead giveaway. And if some lecturer or instructor is telling you that's idiomatic C++ ask for your money back.

PS: Eugen said in a comment that you never see the address of y. Actually you do. It's what the compiler says is the address of x. You can't see the address of x because x hasn't got an address, it's just an alias which is why the compiler creates y.
 
Share this answer
 
v2
Comments
Eugen Podsypalnikov 18-Sep-10 15:06pm    
// Except you never see y...
...and its address as well... :)
Richard MacCutchan 18-Sep-10 15:47pm    
I feel this answer is worth far more than 5; thanks for all that.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900