Move-Assignment mit __property Bug (Klassischer Compiler)



  • Habe gerade einen Bug im RAD Studio 10.1 Berlin Update 2 gefunden, gibt´s den unter 10.2 Tokyo auch noch?
    Der Bug tritt nur mit dem klassischen Compiler auf, der clang übersetzt richtig.

    #pragma argsused
    
    #include <tchar.h>
    #include <string>
    #include <iostream>
    #include <cassert>
    
    class Class1
    {
       std::string Name_;
    
    public:
       Class1() :
          Name_( "Default Name" )
       {
       }
    
       void set_modified( bool Flag )
       {
          std::string local;
          if( Flag )  local = Name;        // move-assignment used! -> Destroys Name
          else        local = "Original";
       }
    
       __property std::string  Name = { read=Name_ , write=Name_ };
    };
    
    class Class2
    {
       Class1   Object_;
    public:
       __property Class1 Object = { read=Object_ };
    };
    
    int _tmain(int argc, _TCHAR* argv[])
    {
       Class2 c2;
       assert( c2.Object.Name == "Default Name" );
       c2.Object.set_modified( true );
       assert( c2.Object.Name == "Default Name" );
    }
    

    Object ist in Class2 als read-only definiert, daher dürfte der Compiler den Aufruf von set_modified auf c2.Object eigentlich nicht zulassen. Macht er aber doch, und behandelt es auch als const. Damit darf in der set_modified Methode (Zeile 21) der move-assignement operator benutzt werden, der allerdings dann Name kaputtschreibt.



  • m.E. ist das Verhalten korrekt, dass set_modified aufgerufen werden kann, denn du lieferst über die Eigenschaft ja das in c2 vorhandene Class1 Objekt zurück.

    Was nicht geht, ist der Eigenschaft Object ein anderes Class1 Objekt zuzuzweisen.

    Oder hab ich da jetzt was falsch verstanden?



  • Das ist halt die Frage, wie sich __property Member verhalten. Liefert ein Member der Form

    __property Object Obj = { read=Obj_ }
    

    Object& oder const Object& zurück? So oder so macht der Compiler was falsch:

    Fall 1)
    Es wird ein Object& zurückgegeben, dann dürfte er den move assignment operator nicht benutzen.

    Fall 2)
    Es wird ein const Object& zurückgegeben, dann dürfte er den move assignment operator benutzen, aber den set_modified Aufruf nicht zulassen.


Log in to reply