const_cast<>

R

R. Anbeeswaran

Hi All,

void main()
{
const int i = 20;
int *p = const_cast<int*>(&i);
*p = 40;
cout <<"i="<< i <<"\t"<<"*p="<<*p<<"\n";
}

In the output of the prog. is :

i=20 *p=40

How is it true? (p is pointing to i). How is the particular address
referenced to two different values?
In the Quick Watch, (Visutal Studio is used for compilation & debug),
the value of 'i' and '*p' are same. But, it is flashed out with the
different values? The result is same in the release mode also.

All assistance are appreciated.

Cheers,
R. Anbeeswaran.
 
J

Jack Klein

Hi All,

void main()

There is no such thing as "void main()" in C++. The ANSI/ISO standard
requires "int main()" ALWAYS. In fact, a conforming C compiler is
required to issue a diagnostic message for "void main()".
{
const int i = 20;
int *p = const_cast<int*>(&i);

Attempting to modify a variable that was defined as const produces
undefined behavior. The C++ standard no longer knows or cares what
your program does. Anything that happens is just as right or wrong as
anything else.
cout <<"i="<< i <<"\t"<<"*p="<<*p<<"\n";
}

In the output of the prog. is :

i=20 *p=40

How is it true? (p is pointing to i). How is the particular address
referenced to two different values?
In the Quick Watch, (Visutal Studio is used for compilation & debug),
the value of 'i' and '*p' are same. But, it is flashed out with the
different values? The result is same in the release mode also.

All assistance are appreciated.

There is no point in asking why a particular compiler produces any
particular results once you invoke undefined behavior.

--
Jack Klein
Home: http://JK-Technology.Com
FAQs for
comp.lang.c http://www.eskimo.com/~scs/C-faq/top.html
comp.lang.c++ http://www.parashift.com/c++-faq-lite/
alt.comp.lang.learn.c-c++ ftp://snurse-l.org/pub/acllc-c++/faq
 
S

Senthilvel Samatharman

R. Anbeeswaran said:
Hi All,

void main()
{
const int i = 20;
int *p = const_cast<int*>(&i);

Ohh..Anbeee..
That results in an undefined behaviour.....
Suppose
int i = 20;
const int j = 40;

const int * pi = &i;
const int * pj = &j;

Now a const cast on pi is safe because the referred object is not a const,
ie int * p = const_cast<int*>(pi) is safe...
But a const_cast on pj would cause undefined behaviour because i is a const
int., ie int *p = const_cast<int*>(pj) results in undefined behaviour
and the value in *p may be anything..

Look into the thread "Safely casting away const" on comp.lang.c++.moderated.



Greetings,
Senthilvel.
 
K

Karl Heinz Buchegger

R. Anbeeswaran said:
Hi All,

void main()
{
const int i = 20;
int *p = const_cast<int*>(&i);
*p = 40;
cout <<"i="<< i <<"\t"<<"*p="<<*p<<"\n";
}

In the output of the prog. is :

i=20 *p=40

How is it true? (p is pointing to i). How is the particular address
referenced to two different values?
In the Quick Watch, (Visutal Studio is used for compilation & debug),
the value of 'i' and '*p' are same. But, it is flashed out with the
different values? The result is same in the release mode also.

What did you expect?
You lied to your compiler and thats what you get.

cont int i = 20;

Here you say: i is 20. Always. Dear compiler you can count on that.

Then you use some tricks to attempt to change the value of i.

But since the compiler trusted you when you said that i always equals 20,
it substituted the value 20 for i in
cout <<"i="<< i <<"\t"<<"*p="<<*p<<"\n";

Never lie to your compiler!
 
E

Ekkehard Morgenstern

Hi R. Anbeeswaran,

R. Anbeeswaran said:
i=20 *p=40

How is it true? (p is pointing to i). How is the particular address
referenced to two different values?

First off, what the others said that it's undefined behaviour to modify a
variable declared as constant is certainly true.

What happens is that the compiler gathers a constant definition for "i",
namely "i=20". It also allocates space for the constant on the stack or in
the data or constant data segment in the executable file. Basically, if the
compiler is smart enough, it will notice that you've taken address of a
constant variable for the purpose of modifying it. Hence, since you casted
away constness the object becomes writable. You can set a compiler option to
raise the warning level during compilations. This might help you to detect
such situations in which the compiler would issue a warning of minor
significance that gets suppressed during default warning level compilation.
(BTW, if the compiler was really smart, it would just put a copy of the
constant in the constant data segment, and when you'd modify it, you'd get
an access violation exception)

So, you have two memory locations: one in the compiler's constant storage,
and one after compiling, on the stack during runtime or in the executable
file.

In your first "cout::eek:perator<<()" call giving "i", the compiler will
replace "i" with the constant "20" that you assigned to it. Hence you should
always imagine that a constant is replaced with its value during compile
time. "p" on the other hand, points to the memory that holds a copy of "i"
in the data segment during runtime. After assigning "40", you get "*p=40" as
output in your cout sequence.

I hope that helps! :)

Regards,
Ekkehard Morgenstern.
 
R

R. Anbeeswaran

Hi Mr. Ekkehard Morgenstern,

Thank you very much for your answer. I understood from your answer & some
of other references and I am concluding here:

"The compiler is using the necessary calculations for the constant variable
to perform the constant folding. So, "cout << i..." is calculated duing the
compile time (as you told, it is from the compiler's constant storage.)
itself. And, Since, '*p' is not constant variable, "...<<*p<<.." should be
calculated duing the runtime."

I'll come to my problem, where I have it. I have a class called
"Electronics". This class can use the attributes, but, the scope of the
maintenance of the attributes is not with in this class. Because, it doesn't
know anything. So, the attributes are 'Const' in "Electronics". The
maintenance is done by someother control class called 'Service'. So, the
result should be reflected from the 'Service' class into the 'Electronics'
class. How should I go for this?

Cheers,
-Anbee-
 
R

Rolf Magnus

R. Anbeeswaran said:
Hi Mr. Ekkehard Morgenstern,

Thank you very much for your answer. I understood from your answer &
some of other references and I am concluding here:

"The compiler is using the necessary calculations for the constant
variable to perform the constant folding. So, "cout << i..." is
calculated duing the compile time (as you told, it is from the
compiler's constant storage.) itself. And, Since, '*p' is not constant
variable, "...<<*p<<.." should be calculated duing the runtime."

That's more or less what happens, yes. The compiler may insert the value
of 20 directly into the code wherever you use i. But if you need a
pointer to i, it must be in memory somewhere, how else could the
address of it be taken? So real storage gets used to put the value of i
into. It might (depending on your system) be possible to change the
content of that memory location with the const_cast trick, but of
course that won't change all the assembler instructions that directly
contain the value of i. Since you told the compiler that i is const
(i.e. it will never change), it is free to do such an optimization.
The rule of thumb is that you may use const_cast _only_ if you know
exactly what you're doing. Almost every occurance of a const_cast is a
sign of a bug or design error. Either the use of the const_cast itself
is the error, or it's used to work around an error in code that cannot
be changed (e.g. a library that has a const missing somewhere).
I'll come to my problem, where I have it. I have a class called
"Electronics". This class can use the attributes,

Whose attributes? Electronics's ones?
but, the scope of the maintenance of the attributes is not with in
this class. Because, it doesn't know anything.

About what? Its own member variables?
So, the attributes are 'Const' in "Electronics". The maintenance is
done by someother control class called 'Service'.

Do you mean that 'Electronics' doesn't change its own member variables,
but 'Service does'? Why are they member variables of 'Electronics'
then? And why are they const if they are supposed to be changed?
So, the result
should be reflected from the 'Service' class into the 'Electronics'
class. How should I go for this?

I don't understand exactly what you want. Could you give a small code
example of your idea?
 
E

Ekkehard Morgenstern

Hi R. Anbeeswaran,

R. Anbeeswaran said:
I'll come to my problem, where I have it. I have a class called
"Electronics". This class can use the attributes, but, the scope of the
maintenance of the attributes is not with in this class. Because, it doesn't
know anything. So, the attributes are 'Const' in "Electronics". The
maintenance is done by someother control class called 'Service'. So, the
result should be reflected from the 'Service' class into the 'Electronics'
class. How should I go for this?

I think I know what you mean.

"const" is used only when you a certain that the value isn't modified later.
Otherwise, don't use "const". You can protect variables by putting them into
the private scope of the class.

class Electronics {
private: // "private:" is not really necessary since when the
class begins, it starts with private, but just to make it clear.
int attribute1;
int attribute2;
public:
int GetAttrib1( void ) const { return attribute1; } // declaring
"GetAttrib1()" as "const" means it doesn't change the object's data.
int GetAttrib2( void ) const { return attribute2; }
void SetAttrib1( int value ) { attribute1 = value; }
void SetAttrib2( int value ) { attribute2 = value; }
};

So, when you need to change the Electronics object from the Service object,
simply call the SetAttrib() methods.

class Service {
private:
Electronics* electr;
public:
void DoStuff( void ) { electr->SetAttrib1( 12345 ); }
};

I hope that helps.

Regards,
Ekkehard Morgenstern.
 

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

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,054
Latest member
TrimKetoBoost

Latest Threads

Top