pointer to const in c++

S

Sean Yang

I wrote a program like this(test.cpp)
and the result is
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
pointer to a =2
const a =1
address of a 0xbfffdd44
address of p 0xbfffdd44
~~~~~~~~~~~~~~~~~~~~~~~~~~~
what on earth the value is in (0xbfffdd44)? Thank you


#include <iostream>
using namespace std;
int main()
{
const int a = 1;
int* p;
p = (int*)&a;
(*p)++;
cout<< "pointer to a ="<<*p<<endl;
cout<< "const a =" << a<< endl;
cout<< "address of a" <<&a<<endl;
cout<< "address of p" <<p<<endl;
return 0;
}
 
R

Ron Natalie

Sean Yang said:
what on earth the value is in (0xbfffdd44)? Thank you

Impossible to tell. You have undefined behavior in that you
changed an object defined as const through your cast. This
is an extremely bad thing to do. The standard puts no constraints
on what might happen.
 
K

Kevin Goodsell

Sean said:
I wrote a program like this(test.cpp)

Please don't send attachments to text groups. There are a number of good
reasons for this, two important ones being 1) people don't trust
attachments and won't open them, and 2) some news servers refuse
messages with attachments so some people will never see the message at all.

Put your code in the body of the message.

http://www.parashift.com/c++-faq-lite/how-to-post.html#faq-5.4
http://www.parashift.com/c++-faq-lite/how-to-post.html#faq-5.8

-Kevin
 
U

Unforgiven

This is undefined behaviour, but my bet is on 2.

I ran this code through Visual C++ .Net 2003, and what happened is this:
When you do cout << *p, the value of *p gets pushed on the stack like this:
0041B1ED mov eax,dword ptr [p]
0041B1F0 mov ecx,dword ptr [eax]
0041B1F2 push ecx
When you do cout << a, the value of a gets pushed on the stack like this:
0041B218 push 1

Because a is a constant, the actual 'read a' part is optimised away and 1 is
just inserted into the program where it should've been.
*P is computed, so at memory location p, which is the same as &a, you'll
find the value 2. But this is never read when using a, because that's
optimised away. This is such a basic optimisation that VC even does it when
optimisation is turned *off*!

The story becomes a little different when you use optimisations though.
Because you only use constants, the value of *p is also precomputed at
compile time, so print it becomes a 'push 2'. Because it's not needed, it's
never put in memory, so what's actually in the memory location is whatever
was there before your program started, there's no way to tell. In fact, the
only reason there still is memory allocated on the stack for a and p is
because you request their addresses. If you hadn't the variables would
probably have been optimised out of the program completely.

Note that this whole story is *very* implementation dependant. A compiler is
free to give warnings or errors about what you're trying to do. If a
compiler decides to put the constant in a write-protected segment of memory
the program would crash.

Bottom-line: don't do it! Also, try using C++ casts. Both
static_cast<int*>(&a) and reinterpret_cast<int*>(&a) woud've given you an
error (at least in VC.NET 2003):
cpptest.cpp(7) : error C2440: 'reinterpret_cast' : cannot convert from
'const int *__w64 ' to 'int *'
Conversion loses qualifiers

You should always use C++ casts, because as this example demonstrates, with
C-style casts you just can't be sure it does what you expect it to do. Right
now you're C-style cast acts equivalent to a const_cast, and as the
documentation so rightly notices about const_cast:
"Depending on the type of the referenced object, a write operation through
the resulting pointer, reference, or pointer to data member might produce
undefined behavior."
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
474,142
Messages
2,570,820
Members
47,367
Latest member
mahdiharooniir

Latest Threads

Top