Frage Möglichkeiten zum versehentlichen Erstellen temporärer Objekte in C ++?


Vor Jahren glaubte ich, dass C im Vergleich zu C ++ absolut sauber war, weil der Compiler keinen Code erzeugen konnte, den man nicht vorhersagen konnte. Ich glaube jetzt, dass Gegenbeispiele das einschließen volatile Schlüsselwort- und Speicherbarrieren (bei Multiprozessor-Programmierung oder Gerätetreibern für Speicherkarten-Hardware-Geräte, wo reine Assemblersprache noch reiner wäre als die Optimierungen eines C-Compilers).

Im Moment versuche ich, die unvorhersehbaren Dinge aufzuzählen, die ein C ++ - Compiler machen kann. Die Hauptbeschwerde, die mir in Bezug auf C ++ in Erinnerung bleibt, ist, dass der Compiler implizit temporäre Objekte instanziiert, aber ich glaube, dass diese Fälle alle erwartet werden können. Die Fälle, an die ich denke, sind:

  • wenn eine Klasse einen Kopierkonstruktor für einen anderen Typ als sich selbst definiert, ohne den explicit Stichwort
  • Wenn eine Klasse einen überladenen Konvertierungsoperator definiert: operator ()
  • wenn eine Funktion ein Objekt nach Wert anstatt nach Referenz annimmt
  • wenn eine Funktion ein Objekt nach Wert anstatt nach Referenz zurückgibt

Gibt es noch andere?


7
2018-02-08 14:17


Ursprung


Antworten:


Ich denke, "unberechenbar" bedeutet "etwas, das dem Standard entspricht, aber anders als das, was der Programmierer beim Schreiben von Code erwartet", oder?

Ich denke, Sie können aus dem Code sehen, wo Objekte instanziiert oder kopiert werden, auch wenn es vielleicht nicht offensichtlich ist. Es könnte jedoch schwer zu verstehen sein.

Einige Dinge werden nur auf bestimmte Arten von (allen?) Compiler-Anbietern implementiert, aber es könnte anders gemacht werden. Z. B. wird die späte Bindung (alias das Aufrufen einer überladenen, virtuellen Methode) üblicherweise unter Verwendung von Funktionszeigern im Hintergrund implementiert. Das ist vielleicht der schnellste Weg, aber ich denke, es könnte anders gemacht werden, und das wäre unerwartet. Ich kenne keinen Compiler, der das anders macht.

Viele Dinge sind unerwartet in dem Sinne, dass C ++ zu komplex ist - kaum jemand versteht die ganze Sprache. So unerwartet hängt auch von Ihrem Wissen ab.


2
2018-02-08 14:28



12.2 Temporäre Objekte

1 Provisorien der Klassenart sind   in verschiedenen Kontexten erstellt: verbindlich   ein rvalue zu einer Referenz (8.5.3),   Rückgabe eines rvalue (6.6.3), a   Konvertierung, die einen Rvalue erstellt   (4.1, 5.2.9, 5.2.11, 5.4), werfend   Ausnahme (15.1), Eingabe eines Handlers   (15.3) und in einigen Initialisierungen   (8.5).

4 Es gibt zwei Kontexte, in denen   Provisorien werden bei a zerstört   anderer Punkt als das Ende der   Fullexpression.

In der Tat schlage ich vor, einen Blick auf die gesamte 12.2 zu werfen

Im Moment versuche ich aufzuzählen   die unvorhersehbaren Dinge ein C ++   Compiler kann. Die Hauptbeschwerde   Das erinnert mich an C ++   dass der Compiler implizit wird   temporäre Objekte instanziieren, aber ich   glaube, diese Fälle können alle sein   erwartet.

Der Compiler erstellt implizit keine Provisorien - er gehorcht dem Standard. Es sei denn natürlich, wenn Sie undefiniertes Verhalten aufrufen. Beachten Sie, dass es etwas gibt, das Kopieroptimierung und Rückgabewert-Optimierung genannt wird, was möglicherweise die Anzahl der Provisorien reduziert, die sonst erstellt würden.


2
2018-02-08 14:36



Ein interessanter Link zu häufigen Fallstricken im Zusammenhang mit diesem Thema:

http://www.gotw.ca/gotw/002.htm


0
2018-02-08 17:13