change a constant by pointer

  • Thread starter want.to.be.professer
  • Start date
W

want.to.be.professer

#include <iostream>
using namespace std;

// Check if N is constant
template <int N>
class ValidateConstInt{};

int main()
{
const int constValue = 12;
const int* pConstValue = &constValue;
int* pValue = const_cast <int*> ( &constValue );

ValidateConstInt <constValue> (); // Check if constValue is
constant

cout << "------------------------------------ " << endl;
cout << " begin: " << endl;
cout << "\t const int constValue = 12; " << endl;
cout << "\t const int* pConstValue = &constValue;"<< endl;
cout << "\t int* pValue = const_cast <int*> (&ConstValue);"<<
endl;
cout << endl;

cout << "------------------------------------ " << endl;
cout << " constValue = " << constValue << endl;
cout << " &constValue = " << &constValue << endl;
cout << " *pConstValue = " << *pConstValue << endl;
cout << " pConstValue = " << pConstValue << endl;
cout << " *pValue = " << *pValue << endl;
cout << " pValue = " << pValue << endl;
cout << endl;

*pValue = 1; // Change the value

cout << "------------------------------------- After *pValue = 1
" << endl;
cout << endl;

cout << " constValue = " << constValue << endl;
cout << " &constValue = " << &constValue << endl;
cout << " *pConstValue = " << *pConstValue << endl;
cout << " pConstValue = " << pConstValue << endl;
cout << " *pValue = " << *pValue << endl;
cout << " pValue = " << pValue << endl;
cout << "------------------------------------ " << endl;
return 0;
}

// ------------- Result:
------------------------------------
begin:
const int constValue = 12;
const int* pConstValue = &constValue;
int* pValue = const_cast <int*> (&ConstValue);

------------------------------------
constValue = 12
&constValue = 0012FF6C
*pConstValue = 12
pConstValue = 0012FF6C
*pValue = 12
pValue = 0012FF6C

------------------------------------- After *pValue = 1

constValue = 12 // not changed
&constValue = 0012FF6C
*pConstValue = 1 // have changed
pConstValue = 0012FF6C
*pValue = 1 // have changed
pValue = 0012FF6C
------------------------------------

The pConstValue and pValue both point to the ConstValue, and the value
access by the point is changed, but constValue has never changed ( and
it shoule not be a constant ). I can not explain, Can somebody help
me ?
 
M

maverik

I try the next:

....
int main()
{ int x = 12;
     const int  constValue  = X;
     const int* pConstValue = &constValue;
     int*       pValue      = const_cast <int*> ( &constValue );
....

And get compiler error:
'ValidateConstInt' : template parameter 'N' : 'constValue' : a local
variable cannot be used as a non-type argument

Perhaps in your case compiler doesn't create constValue, it just uses
its value: 12 (kind of optimization). So you get such a result. By I'm
not shure.
 
P

Pawel Dziepak

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

want.to.be.professer wrote:
The pConstValue and pValue both point to the ConstValue, and the value
access by the point is changed, but constValue has never changed ( and
it shoule not be a constant ). I can not explain, Can somebody help
me ?

According to paragraph 7.1.5.1/4:
"(...) any attempt to modify a const object during its lifetime results
in undefined behavior."
That's why you get that. In fact you compiler optimized constValue, and
put its value to the parts where it was directly used. In other cases
(referencing to constValue through pointers) it was treated as a pointer
to non-cv-qualified object.

Pawel Dziepak
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.9 (GNU/Linux)
Comment: Using GnuPG with Fedora - http://enigmail.mozdev.org

iEYEARECAAYFAkkVhjwACgkQPFW+cUiIHNq59ACdGcVJEcVFYYpUeGbAJ/hEwYMn
7QgAnR2pxba7gWy4eQHDnTKPfTBe8uTI
=fRhq
-----END PGP SIGNATURE-----
 
W

want.to.be.professer

I try the next:

...> int main()

int x = 12;> const int constValue = X;

...

And get compiler error:
'ValidateConstInt' : template parameter 'N' : 'constValue' : a local
variable cannot be used as a non-type argument

Perhaps in your case compiler doesn't create constValue, it just uses
its value: 12 (kind of optimization). So you get such a result. By I'm
not shure.

In my windows XP OS, I used vs2005 and g++ compiler.They both like
this.
 
E

Erik Wikström

#include <iostream>
using namespace std;

// Check if N is constant
template <int N>
class ValidateConstInt{};

int main()
{
const int constValue = 12;
const int* pConstValue = &constValue;
int* pValue = const_cast <int*> ( &constValue );

ValidateConstInt <constValue> (); // Check if constValue is
constant

cout << "------------------------------------ " << endl;
cout << " begin: " << endl;
cout << "\t const int constValue = 12; " << endl;
cout << "\t const int* pConstValue = &constValue;"<< endl;
cout << "\t int* pValue = const_cast <int*> (&ConstValue);"<<
endl;
cout << endl;

cout << "------------------------------------ " << endl;
cout << " constValue = " << constValue << endl;
cout << " &constValue = " << &constValue << endl;
cout << " *pConstValue = " << *pConstValue << endl;
cout << " pConstValue = " << pConstValue << endl;
cout << " *pValue = " << *pValue << endl;
cout << " pValue = " << pValue << endl;
cout << endl;

*pValue = 1; // Change the value

cout << "------------------------------------- After *pValue = 1
" << endl;
cout << endl;

cout << " constValue = " << constValue << endl;
cout << " &constValue = " << &constValue << endl;
cout << " *pConstValue = " << *pConstValue << endl;
cout << " pConstValue = " << pConstValue << endl;
cout << " *pValue = " << *pValue << endl;
cout << " pValue = " << pValue << endl;
cout << "------------------------------------ " << endl;
return 0;
}

// ------------- Result:
------------------------------------
begin:
const int constValue = 12;
const int* pConstValue = &constValue;
int* pValue = const_cast <int*> (&ConstValue);

------------------------------------
constValue = 12
&constValue = 0012FF6C
*pConstValue = 12
pConstValue = 0012FF6C
*pValue = 12
pValue = 0012FF6C

------------------------------------- After *pValue = 1

constValue = 12 // not changed
&constValue = 0012FF6C
*pConstValue = 1 // have changed
pConstValue = 0012FF6C
*pValue = 1 // have changed
pValue = 0012FF6C
------------------------------------

The pConstValue and pValue both point to the ConstValue, and the value
access by the point is changed, but constValue has never changed ( and
it shoule not be a constant ). I can not explain, Can somebody help
me ?

One of the reasons we have constants is that they allow for certain
optimisations. Since the compiler knows the value of constValue it can
skip a lot of stuff it would have to do if it was a variable. If you had
not taken its address the compiler would probably not allocated the
memory for it at all and used the value of 12 wherever constValue was
used. But since you took the its address it had to allocate some memory
for it, but since it knew it was constant it still didn't bother to use
it and did the optimisations anyway.

Notice also that what you did (taking the address of a constant, casting
away the const-ness and using the pointer to change the value) is not
allowed, and with other settings / compiler / OS your program would have
crashed instead because constValue would have been places in read only
memory. In sort, if you do not follow the rules of the languages
anything can happen and no guarantees are given.
 
M

maverik

Notice also that what you did (taking the address of a constant, casting
away the const-ness and using the pointer to change the value) is not
allowed, and with other settings / compiler / OS your program would have
crashed instead because constValue would have been places in read only
memory.

Proof:

write

static const int constValue = 12;

instead of

const int constValue = 12;

The program crashes in this case (WinXP SP1, VC8.0) with exception
that says that I try to write to readonly memory
 
J

JaredGrubb

The pConstValue and pValue both point to the ConstValue, and the value
access by the point is changed, but constValue has never changed ( and
it shoule not be a constant ). I can not explain, Can somebody help
me ?

You're confusing what "const" means... Const means "you cannot change
it" and does NOT mean that "it cannot be changed" (your program is an
example of this!). Change these declarations from "const" to "volatile
const" and your program will work the way you had hoped (constValue
returns 1 after *pValue is altered):
 
J

James Kanze

You're confusing what "const" means... Const means "you cannot
change it" and does NOT mean that "it cannot be changed" (your
program is an example of this!).

It depends. Const has two meanings. In general, you cannot
modify a value throw an expression which refers to an object (an
lvalue expression, in standardese) and has a const type; you can
modify the object through other expressions, however. If the
object itself is const, however (as is the case here), any
attempt to modify it is undefined behavior.
Change these declarations from "const" to "volatile const" and
your program will work the way you had hoped (constValue
returns 1 after *pValue is altered):

It might, or it might not. Undefined behavior is undefined
behavior.

The volatile simply tells the compiler that this object might be
modified by something outside the program. Any attempt to
modify it from within the program is still undefined behavior.
As another poster pointed out, declaring the object static could
very well end up in the attempt to modify it causes a core dump.
The volatile probably won't help here.
 

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
473,994
Messages
2,570,223
Members
46,813
Latest member
lawrwtwinkle111

Latest Threads

Top