using reference to modify the const object

Hi.Experts:
Code following:
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
#include <iostream>
using namespace std;
int main()
{
       int const num=10;
       (long &)num=20;
       cout<<num<<endl;
}
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
I use debugger in VC6.0 to view the assembly code:
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
6:         int const num=10;
00401018   mov         dword ptr [ebp-4],0Ah
7:         (long &)num=20;
0040101F   mov         dword ptr [ebp-4],14h
8:         cout<<num<<endl;
00401026   push        offset std::endl (00401a80)
0040102B   push        0Ah
0040102D   mov         ecx,offset std::cout (00442308)
00401032   call        std::basic_ostream<char,std::char_traits<char> >::operator<< (004010a0)
00401037   mov         ecx,eax
00401039   call        std::basic_ostream<char,std::char_traits<char> >::operator<< (00401050)
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
I use the  (long &) to let compiler compiles successful,and modifies the const variable num.
cout<<num<<endl;
I expected the assembly code:
push        offset std::endl (00401a80)
mov         eax,dword ptr [ebp-4]
push        eax
mov         ecx,offset std::cout (00442308)
...
But why directly use "push        0Ah"?
Could someone tell me why?
THANKS!!

TKDAsked:
Who is Participating?

[Product update] Infrastructure Analysis Tool is now available with Business Accounts.Learn More

x
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

AlexFMCommented:
Nice. Compiler expects that const num is always 10 and sets 10 instead of num in every place. This happens even in Debug configuration, which is supposed to be without any optimizations. Post this to Microsoft.
0
TKDAuthor Commented:
Hi.AlexFM
Those happen are not only in VC but also in G++.
I would like to know how the compiler know "push 0Ah"?
Where the compiler references the "0Ah"?
Could someone tell me?
THX.
0
_nn_Commented:
>> Could someone tell me why?

Because you told the compiler : num is a int const

Now try this :

#include <iostream>
using namespace std;
int main()
{
      int const num=10;
      (long &)num=20;
      cout<<(long &)num<<endl;
}

Yet, I have to understand why you want to use the const specifier if the variable will change over time. It just doesn't make much sense to me...
0
OWASP Proactive Controls

Learn the most important control and control categories that every architect and developer should include in their projects.

AlexFMCommented:
0Ah is 10 from
int const num=10;
0
DexstarCommented:
@TKD:

> But why directly use "push        0Ah"?
> Could someone tell me why?

You should think of this line:
  int const num=10;

As just being a better way of writing this line:
  #define num 10

The compiler will treat them almost the same.  num never takes up any actual memory.

What I found interesting was this:
     6:         int const num=10;

This line shouldn't generate any ASM code.

     7:         (long &)num=20;
     00401018   mov         dword ptr [ebp-4],0Ah
     0040101F   mov         dword ptr [ebp-4],14h
(That line generates both the ASM lines above because you are just copying the value 0ah to a temp variable, and changing the value of the copy.)

Comment out line #7 and I bet both those lines go away.  Let this be a lesson to you:  YOU CAN'T CHANGE A CONST.  DON'T TRY.


Hope That Helps,
Dex*
0
TKDAuthor Commented:
Hi.Experts:
I would not like to change the const object in the program.
I just test the ressult when i add (long &) to const object.
I use (long &) to cheat the compiler to compile successful if i modify the const object.
THX.
0
TKDAuthor Commented:
Hi: Dexstar
int const num=10;  <==>  #define num 10
For Define:
Define is a macro provided by preprocessor.
After preprocessing, the num is replaced by 10 in the program anywhere.
It doesn't has memory in stack frame at run-time.
For const:
Const specifiter tells the compiler that num is a const integer number,and it also has memory in stack frame at run-time.
I think that const is not equivalent to define.
When compiiler compiles a const number or object, the contenct of const object will be put into const data segment. Right???
So,statements : cout<<num<<endl;
Because compiler know num is a const,the compiler directly replaces num by 10 that got from const data segment. Right???
> 7:         (long &)num=20;
>     00401018   mov         dword ptr [ebp-4],0Ah
>     0040101F   mov         dword ptr [ebp-4],14h
>(... because you are just copying the value 0ah to a temp variable, and changing the value of the copy.)
address of variable num is ebp-4.
i am not copying the value 0ah to a temp variable,i copying the value 0AH to the num varialbe.
I don't know whay u talk about.
i changing the value of the num.
THX.
0
DexstarCommented:
@TKD:

Yeah, but your "cheating" of the compiler cost you 2 instructions.  I guess your original question is what is the reason for the "push        0Ah"?  It's because of this line:
     cout<<(long &)num<<endl;

The value of "num" has to be pushed onto the stack for the function call for the << operator.  But since "num" is const, it isn't stored anywhere, and the value is used explicitly.

Does that answer your question?

Dex*
0
DexstarCommented:
I didn't say it was EXACTLY the same.  I said it will have the same affect.

> i am not copying the value 0ah to a temp variable,i copying the value 0AH to the num varialbe.
> I don't know whay u talk about. i changing the value of the num.

The ASM shows you that this is NOT true.  You are NOT changing the value of num.  You are just changing the value of a temporary variable.

The output of your program is going to be "10", which means "num" didn't change at all.

Dex*
0
TKDAuthor Commented:
Hi.Dexstar:
>But since "num" is const, it isn't stored anywhere, and the value is used explicitly.
View:
6:         int const num=10;
00401018   mov         dword ptr [ebp-4],0Ah
Although num is const,it has memory in stack frame. Why it isn't stored anywhere?
I get that the num  is stored in [ebp-4].Right??
0
TKDAuthor Commented:
The ASM show me the const variable num stored in [ebp-4]:
6:         int const num=10;
00401018   mov         dword ptr [ebp-4],0Ah
U means that [ebp-4] is a temporary variable.Right??
I would like to know where the content of const variable num  after compiler compile the code.In const data segment?
THX.
0
AlexFMCommented:
[ebp-4] is local variable on the stack.
0
TKDAuthor Commented:
>[ebp-4] is local variable on the stack.
Yeah,i know that.
But why have to do "mov dword ptr [ebp-4],0Ah"?
Could it not have "mov dword ptr [ebp-4],0Ah"?
What 's the purpose?
Is the const variable num in const data segment?
If not, where the const variable num exists?
THX.
0
DexstarCommented:
@TKD:

num does not exist in the data segment.  It does not exist at all.  It does not take up ANY memory at all.  None.  The purpose of the "00401018   mov         dword ptr [ebp-4],0Ah" is to copy the value of num (10) to a temp variable, so the temp variable can be modified.  "num" does not physically exist in memory as a variable.

I don't know how many other ways to say it.

Dex*
0
AlexFMCommented:
num exists as first local variable in the function, it is allocated on the stack and available through [ebp-n] as any local variable.
0
TKDAuthor Commented:
int main()
{
      int const num=10;
      cout<<num<<endl;
}
Aftering compile-time:
::::::::::::::::::::::::::::::::::::::::::::
int main()
{
      int const num=10;  //still exists!
      cout<<10<<endl;  //num is replaced by 10
}
::::::::::::::::::::::::::::::::::::::::::::
At Run-Time: the const varialbe num is allocated on the stack.
Totally:
(1)num is replaced by 10 in program anywhere at compile-time.
(2)num is still allocated memory on the stack at run-time.
<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
I think above.
Correct me if I am wrong
0
AlexFMCommented:
Right.

>> num is replaced by 10 in program anywhere at compile-time.
Yes, and as your sample shows, C++ compiler is not 100% correct in this case.

To complete this research, check this also in the Release version.
0
TKDAuthor Commented:
>>C++ compiler is not 100% correct in this case.
What's mean??? =.=???
In the release version,the compiler compiles successful, and output is 10.
0
TKDAuthor Commented:
I find a problem between (int &) and (long &),but i don't know what's different between them.
View:
(1)
void main()
{
      const int num = 10;
      (int &)num = 20;
      cout<<num<<endl;
      cout<<(int &)num<<endl;
}
ASM code:
11:       const int num = 10;
00401908   mov         dword ptr [ebp-4],0Ah
12:       (int &)num = 20;
0040190F   mov         dword ptr [ebp-4],14h
...
14:       cout<<(int &)num<<endl;
0040192E   push        offset @ILT+350(std::endl) (00401163)
00401933   push        0Ah
00401935   mov         ecx,offset std::cout (00481bd8)
...
<<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>
(2)
View:
void main()
{
      const int num = 10;
      (int &)num = 20;
      cout<<num<<endl;
      cout<<(long &)num<<endl;
}
ASM code:
11:       const int num = 10;
00401908   mov         dword ptr [ebp-4],0Ah
12:       (int &)num = 20;
0040190F   mov         dword ptr [ebp-4],14h
...
14:       cout<<(long &)num<<endl;
0040192E   push        offset @ILT+350(std::endl) (00401163)
00401933   mov         eax,dword ptr [ebp-4]
00401936   push        eax
...
<<<<<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>>>>>>>>>>>>>
why use (int &) the ASM code :  "push  0Ah"?
What's different between (int &) and (long &)???
Could someone tell me?
THX.
0
DexstarCommented:
> (1)num is replaced by 10 in program anywhere at compile-time.

Yes, that's right.

> (2)num is still allocated memory on the stack at run-time.

No, that isn't right.  Where do you see it being allocated?  The only thing I see is it being PUSHed onto the stack (push 0Ah).  There is NEVER memory allocated for a CONST.

You see this code:
     14:       cout<<(long &)num<<endl;
     0040192E   push        offset @ILT+350(std::endl) (00401163)
     00401933   mov         eax,dword ptr [ebp-4]
     00401936   push        eax

BECAUSE you cast num to a (long&).  In order to complete the cast, the compiler makes a COPY of the variable (in register EBP).  It moves it to EAX, and then pushes it onto the stack.

In the other version, it doesn't need to make a copy to complete the cast.

Dex*

0
TKDAuthor Commented:
(1)
I see that it allocated:
11:       const int num = 10;
00401908   mov         dword ptr [ebp-4],0Ah
I think that the CONST objects have allocated memory.
So you can addresse of CONST object,following:
const int *pctr=0;
const int num = 20;
pctr = &num;
That's the difference between const and define.
(2)
In VC6.0,the sizeof(long &)=sizeof(int &)=sizeof(long)=sizeof(int)
why (long &) do cast but (int &) not???
I wouldlike to get more explain.
THX.
0
DexstarCommented:
Well, I that the line you mentioned is where it allocates the TEMPORARY variable, because it immediately overwrites it with the value of 14h.

Try this.  Compile this program:
     #include <iostream>
     using namespace std;
     int main()
     {
           const long num=10;
           /*(long &)num=20;*/
           cout<<num<<endl;
     }

And post the ASM output that it creates.

Dex*
0
TKDAuthor Commented:
6:               const long num=10;
00401578   mov         dword ptr [ebp-4],0Ah
7:               /*(long &)num=20;*/
8:               cout<<num<<endl;
0040157F   push        offset @ILT+195(std::endl) (004010c8)
00401584   push        0Ah
00401586   mov         ecx,offset std::cout (004767e0)
0040158B   call        @ILT+245(std::basic_ostream...
0
TKDAuthor Commented:
U say that ebp-4 is not the memory of const variable num.
U say that ebp-4 is a temporary variable  of const variable num.
Right???
0
DexstarCommented:
Interesting.  Is that a debug or a release build?  I think that a release build might be missing that extra line.
0
TKDAuthor Commented:
In Debgu Version.
Could u tell how to prove that??
THX.
0
DexstarCommented:
Sure enough!

On VS.NET, in a debug the ASM for main was this:
      004322D0  push        ebp  
      [SNIP...]
      004322EC  rep stos    dword ptr [edi]
                  const long num=10;
      004322EE  mov         dword ptr [num],0Ah
                  /*(long &)num=20;*/
                  cout<<num<<endl;
      004322F5  push        offset std::endl (42E8EDh)
      004322FA  push        0Ah  
      004322FC  mov         ecx,offset std::cout (49D594h)
      00432301  call        std::basic_ostream<char,std::char_traits<char> >::operator<< (42EAF0h)
      [SNIP]

The release build, the ASM was this:
      00401630  push        esi  
                  const long num=10;
                  /*(long &)num=20;*/
                  cout<<num<<endl;
      00401631  push        0Ah  
      00401633  mov         ecx,offset std::cout (429B5Ch)
      [SNIP]

I believe it was AlexFM who said to look at the release build to verify your results.  For the most part, the release build is the only one that matters.

Dex*
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
DexstarCommented:
Want more proof?  If you put back the line that I took out, the release build is the same as above.

There is no memory allocated for const variables... :)
0
TKDAuthor Commented:
THX.
0
TKDAuthor Commented:
But i find:
      const int num = 20;
      (int &)num=10;
      cout<<(long &)num;
      cout<<(int &)num;
      cout<<num;
the assembly code in Release build:
00401000   push        0Ah
00401002   mov         ecx,offset std::cout (00427318)
00401007   call        std::basic_ostream<char,std::char_traits<char> >::operator<< (00401260)
6:                const int num = 20;
7:                (int &)num=10;
8:                cout<<(long &)num;
9:                cout<<(int &)num;
0040100C   push        14h
0040100E   mov         ecx,offset std::cout (00427318)
00401013   call        std::basic_ostream<char,std::char_traits<char> >::operator<< (00401030)
10:               cout<<num;
00401018   push        14h
0040101A   mov         ecx,offset std::cout (00427318)
0040101F   call        std::basic_ostream<char,std::char_traits<char> >::operator<< (00401030)

How do compiler to know  0Ah of "push 0Ah"????
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
C++

From novice to tech pro — start learning today.