I had an article, but I lost it. It showed and described a couple of C/C++ tricks that people should be careful. One of them interested me but now that I am trying to repli
Some of these answers point out that the compiler can optimize away the variable 'a' since it is declared const. If you really want to be able to change the value of a then you need to mark it as volatile
const volatile int a = 3; // I promise i won't change a
int *ptr = (int *)&a;
(*ptr) = 5; // I'm a liar, a is now 5
Of course, declaring something as const volatile should really illustrate just how silly this is.
you need to cast away the constness:
linux ~ $ cat constTest.c
#include <stdio.h>
void modA( int *x )
{
*x = 7;
}
int main( void )
{
const int a = 3; // I promisse i won't change a
int *ptr;
ptr = (int*)( &a );
printf( "A=%d\n", a );
*ptr = 5; // I'm a liar, a is now 5
printf( "A=%d\n", a );
*((int*)(&a)) = 6;
printf( "A=%d\n", a );
modA( (int*)( &a ));
printf( "A=%d\n", a );
return 0;
}
linux ~ $ gcc constTest.c -o constTest
linux ~ $ ./constTest
A=3
A=5
A=6
A=7
linux ~ $ g++ constTest.c -o constTest
linux ~ $ ./constTest
A=3
A=3
A=3
A=3
also the common answer doesn't work in g++ 4.1.2
linux ~ $ cat constTest2.cpp
#include <iostream>
using namespace std;
int main( void )
{
const int a = 3; // I promisse i won't change a
int *ptr;
ptr = const_cast<int*>( &a );
cout << "A=" << a << endl;
*ptr = 5; // I'm a liar, a is now 5
cout << "A=" << a << endl;
return 0;
}
linux ~ $ g++ constTest2.cpp -o constTest2
linux ~ $ ./constTest2
A=3
A=3
linux ~ $
btw.. this is never recommended... I found that g++ doesn't allow this to happen.. so that may be the issue you are experiencing.
Note any attempt to cast away constness is undefined by the standard. From 7.1.5.1 of the standard:
Except that any class member declared mutable can be modified, any attempt to modify a const object during its lifetime results in undefined behavior.
And right after this example is used:
const int* ciq = new const int (3); // initialized as required
int* iq = const_cast<int*>(ciq); // cast required
*iq = 4; // undefined: modifies a const object
So in short what you want to do isn't possible using standard C++.
Further when the compiler encounters a declaration like
const int a = 3; // I promisse i won't change a
it is free to replace any occurance of 'a' with 3 (effectively doing the same thing as #define a 3)
The step you're missing is that you don't need the int* pointer. The line:
const int *ptr_to_a = &a; // I still promiss i won't change a;
actually says you won't change ptr_to_a, not a. So if you changed your code to read like this:
const int a = 3; // I promise I won't change a
const int *ptr_to_a = &a; // I promise I won't change ptr_to_a, not a.
(*ptr_to_a) = 5; // a is now 5
a is now 5. You can change a through ptr_to_a without any warning.
EDIT:
The above is incorrect. It turns out I was confusing a similar trick with a shared_ptr, in which you can get access to the raw pointer and modify the internal data value without firing off any warnings. That is:
#include <iostream>
#include <boost/shared_ptr.hpp>
int main()
{
const boost::shared_ptr<int>* a = new boost::shared_ptr<int>(new int(3));
*(a->get()) = 5;
std::cout << "A is: " << *(a->get()) << std::endl;
return 0;
}
Will produce 5.
const int foo = 42;
const int *pfoo = &foo;
const void *t = pfoo;
void *s = &t; // pointer to pointer to int
int **z = (int **)s; // pointer to int
**z = 0;
#include<iostream>
int main( void )
{
int i = 3;
const int *pi = &i;
int *pj = (int*)&i;
*pj = 4;
getchar();
return 0;
}