2016-10-05 4 views
7

Angenommen, eine Funktion wie diese gibt es:std :: Bewe- Wie Programmierer zu warnen, nicht zu verwenden * bewegt von * Objekt

int * func() 
{ 
    std::unique_ptr<int> ptr(new int(3)); 
    //Few more lines of code 

    //then one function added where programmer writes like some thing 

    SOME_OTHER_FUNC(std::move(ptr)); 

    return ptr.get(); 
} 



void SOME_OTHER_FUNC(std::unique_ptr<int> arg_ptr) 
{ 
} 

Gibt es eine Möglichkeit Programmierer zu warnen, solche Fehler mit std::move zu vermeiden? Hier geht es nicht nur um unique_ptr sondern auch um andere Objekte.

Gibt es einen Mechanismus, um eine Warnung zu generieren, wenn wir ein Objekt von unangemessen verwendet haben?

+0

nicht sicher, ob duplicate aber nahe themenbezogen: http://stackoverflow.com/questions/39413502/why-should-a-move-constructor-or-move-assignment-operator-clear-its-argument/39413587# 39413587 – Hayt

+1

Ich erwarte, dass Compiler-Schreiber eine Warnung für die Verwendung von allem erfinden, das in einen rvalue umgewandelt wurde, beispielsweise durch 'std :: move'. Wenn es Ihnen weh tut, sollten Sie einen Patch an den Autor Ihres Compilers schicken! –

+0

@TobySpeight Ich bin skeptisch, dass eine solche Warnung eingeführt werden würde. Typen können Move-Konstruktoren/Zuweisungsoperatoren haben, die das Original in einem (teilweise oder sogar vollständig) spezifizierten Zustand belassen, und bestimmte (vielleicht sogar alle) Operationen würden wohldefiniertes Verhalten haben. Wie könnte der Compiler wissen, ob die Verwendung von vom Objekt verschobenem Objekt unbeabsichtigt war? – user2079303

Antwort

15

std::moveist die Warnung. Wenn Ihre Programmierer das nicht verstehen, müssen Sie sie besser erziehen. Wenn die Funktion so lang ist, dass der Programmierer den Zug vernünftig übersehen kann, müssen Sie Ihre Funktion umgestalten, um sie kürzer zu machen.

+2

Oder, begrenzen Sie den Umfang der 'move''d von der Variable, so dass seine Lebensdauer Ende und Anfang ist genau neben, wo es bewegt wird. – Yakk

+1

"*' std :: move "ist die Warnung. *" Was gesagt wurde, war, dass das Komitee sehr viel Mühe hatte, * force * dich zu zwingen, 'std :: move' zu ​​verwenden, um sicherzustellen, dass es klar ist an alle, die den Code lesen, von dem das Objekt verschoben wurde. Und manche Leute verstehen es immer noch nicht. –

+1

@NicolBolas Jeder weiß, dass sich 'std :: move' nicht bewegt und' std :: forward' nicht weiterleitet. – Yakk

0

Nicht jedes Problem kann oder sollte im Quellcode gelöst werden.

  1. Verwenden unique_ptr ist ein Implementierungsdetail; kapseln es ein.

  2. Geben Sie Vor- und Nachbedingungen für die Funktions- und Verwendungstests an.

+3

Nicht jedes Problem wird durch Abstraktion gelöst. Die Tatsache, dass Ihre Ressource verschoben werden kann und danach ungültig wird, kann nicht durch Abstraktion gelöst werden. Perfekte Tests und Testabdeckung lösen alles auf die gleiche Art und Weise, wie das Schreiben von perfektem Code alles löst. Perfektere Tests und perfekterer Code machen die Dinge besser, aber "Tests schreiben, um das abzudecken" ist ungefähr so ​​nützlich wie "tue es nicht an erster Stelle". – Yakk

+0

Sie haben den Punkt der Vor- und Nachbedingungen verpasst. – knivil

0

Es wäre schön, wenn der Compiler hilft, oder? Es gibt gute Gründe, es nicht so einfach ist, wie Sie vielleicht denken:

  1. std::move() nicht Magie ist, und man konnte eine ähnliche Funktion des eigenen schreiben. Wie würde der Compiler wissen, dass Ihre neue Funktion genauso behandelt werden muss? Sie benötigen ein Standardattribut, mit dem Sie die Funktion dekorieren können. Wenn Sie die Warnung spezifisch für die genaue Funktion std::move machen, codieren Sie das Wissen der Standardbibliothek in den Sprachcompiler¹.
  2. Obwohl im Allgemeinen einem verschobenen Objekt nur zugewiesen oder zerstört werden kann, können einige Klassen stärkere Garantien für den Status "verschoben aus" geben (z. B. könnte ein Container als gültige leere Sammlung dokumentiert werden) zugezogen von). Wie können Sie dem Compiler sagen, welche Operationen für bestimmte verschobene Objekte wie diese sicher sind?

¹ Gegenargument: Compiler bereits etwas ähnliches tun, natürlich, wenn Formatstrings für std::printf() und std::scanf() Familien von Funktionen zu validieren.

Verwandte Themen