Solved

using reference to modify the const object

Posted on 2003-11-28
31
678 Views
Last Modified: 2008-02-01
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!!

0
Comment
Question by:TKD
  • 16
  • 9
  • 5
  • +1
31 Comments
 
LVL 48

Expert Comment

by:AlexFM
ID: 9842136
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
 

Author Comment

by:TKD
ID: 9842360
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
 
LVL 16

Expert Comment

by:_nn_
ID: 9842903
>> 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
 
LVL 48

Expert Comment

by:AlexFM
ID: 9843152
0Ah is 10 from
int const num=10;
0
 
LVL 19

Expert Comment

by:Dexstar
ID: 9843920
@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
 

Author Comment

by:TKD
ID: 9844196
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
 

Author Comment

by:TKD
ID: 9844230
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
 
LVL 19

Expert Comment

by:Dexstar
ID: 9844238
@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
 
LVL 19

Expert Comment

by:Dexstar
ID: 9844249
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
 

Author Comment

by:TKD
ID: 9844319
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
 

Author Comment

by:TKD
ID: 9844324
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
 
LVL 48

Expert Comment

by:AlexFM
ID: 9844557
[ebp-4] is local variable on the stack.
0
 

Author Comment

by:TKD
ID: 9844704
>[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
 
LVL 19

Expert Comment

by:Dexstar
ID: 9844717
@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
 
LVL 48

Expert Comment

by:AlexFM
ID: 9844781
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
Enabling OSINT in Activity Based Intelligence

Activity based intelligence (ABI) requires access to all available sources of data. Recorded Future allows analysts to observe structured data on the open, deep, and dark web.

 

Author Comment

by:TKD
ID: 9844834
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
 
LVL 48

Expert Comment

by:AlexFM
ID: 9844864
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
 

Author Comment

by:TKD
ID: 9844924
>>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
 

Author Comment

by:TKD
ID: 9845232
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
 
LVL 19

Expert Comment

by:Dexstar
ID: 9845540
> (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
 

Author Comment

by:TKD
ID: 9847817
(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
 
LVL 19

Expert Comment

by:Dexstar
ID: 9847837
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
 

Author Comment

by:TKD
ID: 9847850
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
 

Author Comment

by:TKD
ID: 9847865
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
 
LVL 19

Expert Comment

by:Dexstar
ID: 9847888
Interesting.  Is that a debug or a release build?  I think that a release build might be missing that extra line.
0
 

Author Comment

by:TKD
ID: 9847906
In Debgu Version.
Could u tell how to prove that??
THX.
0
 
LVL 19

Accepted Solution

by:
Dexstar earned 50 total points
ID: 9847943
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
 
LVL 19

Expert Comment

by:Dexstar
ID: 9847994
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
 

Author Comment

by:TKD
ID: 9848106
THX.
0
 

Author Comment

by:TKD
ID: 9848405
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
 

Author Comment

by:TKD
ID: 9848442
0

Featured Post

How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

Join & Write a Comment

Templates For Beginners Or How To Encourage The Compiler To Work For You Introduction This tutorial is targeted at the reader who is, perhaps, familiar with the basics of C++ but would prefer a little slower introduction to the more ad…
Container Orchestration platforms empower organizations to scale their apps at an exceptional rate. This is the reason numerous innovation-driven companies are moving apps to an appropriated datacenter wide platform that empowers them to scale at a …
The viewer will learn how to pass data into a function in C++. This is one step further in using functions. Instead of only printing text onto the console, the function will be able to perform calculations with argumentents given by the user.
The viewer will learn additional member functions of the vector class. Specifically, the capacity and swap member functions will be introduced.

760 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

20 Experts available now in Live!

Get 1:1 Help Now