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."