   C++ self assignment disappears?
  VC++ 2005 EEI thought there was never inlining/optmising away of any sort in a debug build. Disabled (/Od) optimisations, inline: default.int main (){004129F0  push   ebp  004129F1  mov    ebp,esp 004129F3  sub    esp,780h 004129F9  push   ebx  004129FA  push   esi  004129FB  push   edi  004129FC  lea    edi,[ebp-780h] 00412A02  mov    ecx,1E0h 00412A07  mov    eax,0CCCCCCCCh 00412A0C  rep stos    dword ptr es:[edi] 00412A0E  mov    eax,dword ptr [___security_cookie (43B0DCh)] 00412A13  xor    eax,ebp 00412A15  mov    dword ptr [ebp-4],eax String256string256 (StrConst ("string256"));00412A18  push   0Ah  00412A1A  push   offset string "string256" (436820h) 00412A1F  lea    ecx,[ebp-77Ch] 00412A25  call   string_class::StrConstClass::StrConstClass (4111FEh) 00412A2A  push   eax  00412A2B  lea    ecx,[ebp-164h] 00412A31  call   string_class::String<256>::String<256> (41166Dh) string256 = string256;00412A36  mov    ecx,41h 00412A3B  lea    esi,[ebp-164h] 00412A41  lea    edi,[ebp-164h] 00412A47  rep movs    dword ptr es:[edi],dword ptr [esi] return 0;00412A49  mov    dword ptr [ebp-76Ch],0 00412A53  lea    ecx,[ebp-164h] 00412A59  call   string_class::String<256>::~String<256> (411758h) 00412A5E  mov    eax,dword ptr [ebp-76Ch] }I was expecting operator= to be called, but I'm not not seeing it. I'm seeing the calls to the constructor and destructor okay. I'm not an expert in reading assembly, mind. I have seen the compiler do some remarkable (I thought) things like replacing loops with a call to memset for example, but that was in a release build.Edit: Unless it's an optimisation like RVO, that needs to applied in both debug and release otherwise there'd be inconsistencies between builds.   
  I see a 'mov'. Hence I'm satisfied...Seriously though: maybe self-assignment is just so trivial that it is rejected early (as with an extra semicolon).   ;  Debug builds typically have inlining set to 'No', but you have it as 'Default'.  Assuming you wrote the operator=() code inside the class itself then this is equivalent to including the 'inline' keyword, hence the inlined copy.;00412A36  mov    ecx,41h 00412A3B  lea    esi,[ebp-164h] 00412A41  lea    edi,[ebp-164h] 00412A47  rep movs    dword ptr es:[edi],dword ptr [esi] It has been inlined. See how it inits esi and edi using the same address, setup ecx with a constant and then issue a "rep movs" which will copy 'ecx' dwords from [esi] to [edi]. To anwser your question: it is still there. My idea is that since the string is a constant size string (256+1 bytes probably) it may not even have an operator=(). As a consequence, the compiler replace "string256 = string256" by a trivial copy. Regards,;  There is no 'No' option for inlining in VC++ 2005 EE that I can see. Only 'default', '__inline only' and 'Any suitable'.joanusdmentia got me thinking that it could be because of the implementation of operator= being in the class, that it would be inlined even in debug.string_c.GetData ();00414BB7  lea    ecx,[ebp-178h]00414BBD  call   string_class::String<8>::GetData (4137DAh)const int GetData () { return 12345; }However, GetData there has been defined in the class, and it's returning a constant int. If that isn't a candidate for inlining, I don't know what is.I wonder if there's something wrong with my operator= implementation. Is that rep movs stuff what the compiler generates for bitwise copies in general? I just did a test and it appears to be so...Okay, this is interesting:// Different objects, same typestring256 = string256_2;00414BC4  mov    ecx,41h00414BC9  lea    esi,[ebp-224h]00414BCF  lea    edi,[ebp-118h]00414BD5  rep movs    dword ptr es:[edi],dword ptr [esi]// Different objects, different typestring256 = string64;00414BA4  lea    eax,[ebp-164h]00414BAA  push   eax  00414BAB  lea    ecx,[ebp-118h]00414BB1  call   string_class::String<256>::operator=<64> (413D66h)So it's not so much the self assignment that's causing the confusion. Even with different objects, it still doesn't call operator=.Maybe it's time I revealed the code for operator=:template<size_t size>class String{...template<size_t other_size>String<size>& operator= (const String<other_size>& other){    Assert (string != other.AsCStr (), "Self assignment found.");    memcpy (string, other.AsCStr (), LengthForString (other));    length = other.Length ();    string[length] = '\0';    return *this;}...};Why is this template used for different String types(sizes), but for the same type, it appears to be outputting bitwise copy stuff and ignoring this template. Is there a rule that 'size' and 'other_size' cannot be the same?Or is my diagnosis completely wrong?Edit:Okay, I just implemented another template for operator=:template<size_t size>class String{...String<size>& operator= (const String<size>& other){    Assert (string != other.AsCStr (), "Self assignment found.");    memcpy (string, other.AsCStr (), LengthForString (other));    length = other.Length ();    string[length] = '\0';    return *this;}...};And now it appears to be using THAT template when assigning between Strings of the same type. I'm confused as to why the other template didn't work :\   ;Quote:Original post by Ro_AkiraThere is no 'No' option for inlining in VC++ 2005 EE that I can see. Only 'default', '__inline only' and 'Any suitable'.My bad, your absolutely right.As for your templates, I believe that the templated operator=() will not be recognized as the copy construct assignment operator so the compiler will perform the basic copy instead (ie. theres no function to call).  When you explictly define your own later, it gets called.[Edited by - joanusdmentia on June 4, 2006 5:58:55 PM];  I believe I understand what you mean, you have me a little confused with the "templated operator=() will not be recognized as the copy construct" part. I understand that operator= can be replaced with the use of the copy constructor during initialisation, but in my code, it appears to be an explicit use of operator=. I don't understand the connection with the copy constructor in this case.But I think I know what you mean:// Not recognised for use as a same type operator=// Is it because the use of <size> and <other_size> implicitly indicates/requires // different types?template<size_t other_size>String<size>& operator= (const String<other_size>& other)// We need to implement this one also, for when we have the same typeString<size>& operator= (const String<size>& other)Thanks for the help all! You got me pointing in the right direction!   ;  string256 test = "Test";string256 copy_ctor = test;That code will not invoke operator=, it will invoke the copy ctor.  It is the same as writing:string256 copy_ctor(test);string256 op_eq;op_eq = test;That code should actually invoke operator=.   ;Quote:Original post by Ro_AkiraI believe I understand what you mean, you have me a little confused with the "templated operator=() will not be recognized as the copy construct" part.Sorry, no idea why I said copy construct there, I mean't assignment operator [smile]To expand a little, consider the following:template<typename T>void func(T val){    std::cout << "Templated func()" << std::endl;}void func(int val){    std::cout << "Overloaded func()" << std::endl;}int main(){    func(1);    func<int>(1);}Despite what it looks like the second func(int) is NOT a specialisation of the first, it's an overload.  In otherwords, calling func<int>(1) would NOT call func(int).  Now looking at this through a mirror and applying it to your situation, performing an assignment with the same types will call operator=(const T&), which is an overload of operator= instead of being a specialisation of your template as your expecting.;  Aha! I understand completely! Thank you very much!   