doubt in basic c++ code

F

fintracker

hi,

i just started learning c++, and i tried this sample program. i
expected output to be 20 and 20 but i got 10 and 20. 'i' has not
changed, but the address of i and value of ptr are same. can some one
please clarify.

#include <iostream>
using namespace std;

int main()
{
const int i = 10;
int* ptr = const_cast<int*>(&i);
*ptr = 20;

cout << "i: " << i << endl;
cout << "ptr: " << *ptr << endl;
return 0;
}

TIA
fin.
 
R

Rolf Magnus

hi,

i just started learning c++, and i tried this sample program. i
expected output to be 20 and 20 but i got 10 and 20. 'i' has not
changed, but the address of i and value of ptr are same. can some one
please clarify.

#include <iostream>
using namespace std;

int main()
{
const int i = 10;

Ok, you defined a constant, i.e. an object that never changes.
int* ptr = const_cast<int*>(&i);

Here, you cast away the constness, effectively taking the responsibility to
never try to change it. The compiler cannot protect you from it anymore.
*ptr = 20;

And here, you try to change the constant. The result of that is undefined.
 
G

gMorphus

In addition to that, what happens using VC6, is optimization of the
code.
The compiler knows that 'i' is a constant and replaces its instances
through out the code with the initialized value.
 
J

jackdorse

In addition to that, what happens using VC6, is optimization of the
code.
The compiler knows that 'i' is a constant and replaces its instances
through out the code with the initialized value.

thats right !! compiler should replace the i occurences with the
value(constant folding - related to compiler optimization).

it is done in order to save memory. compiler will nt hv to allocate
memory for such const variables.

bt when we are dealing with the address of such const variables(as we
are in this case), it should allocate memory and thereby it should not
replace the occurences. (Theoretically).

I hv tried to run the code on several compilers, bt same problem.

Also when u use const or u use #define, the VC6 compiler generates same
assembly code for both. which is very confusing.
 
R

Rolf Magnus

jackdorse said:
thats right !! compiler should replace the i occurences with the
value(constant folding - related to compiler optimization).

That's what usually happens in practise. However, with respect to standard
C++, that doesn't matter much. This only important thing here is that the
result is undefined.
it is done in order to save memory.

Also to save execution time, because all calculations that are based on
constants can be done at compile time.
compiler will nt hv to allocate memory for such const variables.

That depends.
bt when we are dealing with the address of such const variables(as we
are in this case), it should allocate memory and thereby it should not
replace the occurences. (Theoretically).

It doesn't matter if the constant has a memory location or not. The compiler
can (and usually will) still choose to use the value directly wherever it
wants.
I hv tried to run the code on several compilers, bt same problem.

Also when u use const or u use #define, the VC6 compiler generates same
assembly code for both. which is very confusing.

Why?
 
J

jackdorse

Rolf said:
That's what usually happens in practise. However, with respect to standard
C++, that doesn't matter much. This only important thing here is that the
result is undefined.


Also to save execution time, because all calculations that are based on
constants can be done at compile time.


That depends.


It doesn't matter if the constant has a memory location or not. The compiler
can (and usually will) still choose to use the value directly wherever it
wants.


Why?

In case of #define .. the compiler, simply replaces the occurences ...
tht is quite understood. But when it is const int i; there shud be some
memory location reserved, instead of merely replacing the occurences.
(Atleast when we are taking the address of it). (pls refer the assembly
code generated, u ll get a better idea)

i also tried printing the value using *(&i) --> bt still the compiler
replaces it with the value. (compilers can get a bit oversmart
sometimes ... :) )
 
R

Rolf Magnus

jackdorse said:
In case of #define .. the compiler, simply replaces the occurences ...
tht is quite understood. But when it is const int i; there shud be some
memory location reserved, instead of merely replacing the occurences.
(Atleast when we are taking the address of it).

Yes, when you are taking the address of it, the data might actually be put
into a memory location, dedpending on what you use the pointer for and on
how you defined the constant.
(pls refer the assembly code generated, u ll get a better idea)

What I know from having done so is that the compiler tends to do many
optimizations I didn't expect and not do optimizations I would have
expected. It's not wise to depend on the optimzation behavior of the
compiler.
i also tried printing the value using *(&i) --> bt still the compiler
replaces it with the value. (compilers can get a bit oversmart
sometimes ... :) )

If you want a real memory access, try to define the constant as volatile.
However, I don't think that this kind of working around your own
limitations (making an object that you plan to modify const) is something
to be ever considered.
 
B

Bo Persson

jackdorse said:
thats right !! compiler should replace the i occurences with the
value(constant folding - related to compiler optimization).

it is done in order to save memory. compiler will nt hv to allocate
memory for such const variables.

bt when we are dealing with the address of such const variables(as
we
are in this case), it should allocate memory and thereby it should
not
replace the occurences. (Theoretically).

But the C++ standard also says that you are not allowed to cast away
constness from an object that is actually declared const. If you do
that anyway, the compiler doesn't have to follow the rules either! :)

If you do it like:

int i = 10;
const int* j = &i;
int* ptr = const_cast<int*>(j); // this is ok
*ptr = 20;

it will work. As the pointer j points to a variable that is not really
const, you can cast away the constness from the pointer.


Bo Persson
 

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,764
Messages
2,569,565
Members
45,041
Latest member
RomeoFarnh

Latest Threads

Top