Wie finde ich heraus, welche Funktionen der Compiler generiert hat?

11

Ich kenne vom Compiler generierte Funktionen, die Dreierregel und die Fünferregel. In realen Szenarien ist es möglicherweise nicht trivial, genau herauszufinden, welche der vom Compiler generierten Funktionen (Konstruktoren, Zuweisungsoperatoren, Destruktoren) tatsächlich vom Compiler erstellt wurden.

Gibt es eine Möglichkeit, die vom Compiler generierten Funktionen für eine bestimmte Klasse aufzulisten?

Ich interessiere mich hauptsächlich für Visual Studio 2019 und Xcode, aber eine generische Lösung wäre noch willkommener.

Helge Klein
quelle

Antworten:

11

Die Regeln sind kompliziert. Ich werde aus einer anderen Antwort stehlen , die eine Tabelle aus Howard Hinnants Präsentation zitiert .

Geben Sie hier die Bildbeschreibung ein

Die Moral hier ist, dass eine gute Praxis darin besteht, sich nicht auf implizite Compiler-Deklarationen zu verlassen und explizit jedes spezielle Mitglied zu deklarieren (je nach Ihren Anforderungen als standardmäßig oder gelöscht).

Bolov
quelle
Wenn Sie jedes spezielle Mitglied explizit deklarieren, verlieren Sie den Status "nicht deklariert" für spezielle Elemente für den Verschiebungskonstruktor und den Zuweisungsoperator.
Maxim Egorushkin
@MaximEgorushkin Mein Ziel ist es, sie als standardmäßig zu deklarieren, wenn Sie sie benötigen (obwohl Standard immer noch bedeuten kann, dass sie nicht deklariert sind) oder zu löschen, wenn Sie sie nicht möchten.
Bolov
2
@bolov Das Diagramm ist nützlich, aber dies beantwortet meine Frage nicht. Ich möchte herausfinden, welche Funktionen tatsächlich vom Compiler generiert wurden. Mit anderen Worten: Ich frage nicht, was theoretisch passieren soll, sondern was in der Praxis passiert.
Helge Klein
1
@ tjwrona1992: Mit diesem Argument müssten wir unseren Code niemals testen, da wir wissen würden, dass ein Fehler darin bestehen muss, wenn der Compiler etwas anderes als beabsichtigt tut.
Ruakh
1
@ tjwrona1992: Ja genau. Um zu sehen, was Ihr Compiler generiert hat, müssen Sie nicht überprüfen, ob der Compiler korrekt ist, sondern ob Sie dem Compiler die richtige Eingabe gegeben haben.
Ruakh
7

"Gibt es eine Möglichkeit, die vom Compiler generierten Funktionen für eine bestimmte Klasse aufzulisten?"

Natürlich gibt es. Auf Linux (und anderen Unix - Systemen) können Sie verwenden nm, readelfund objdumpauf das erzeugte Objektdateien / Bibliotheken / ausführbare sie zu zerlegen und untersuchen alle exportierten Symbole (und vieles mehr).

Ich weiß, dass es unter Windows ähnliche Tools gibt , aber das ist keine Plattform, mit der ich viel arbeite. Daher kann ich dort leider keine genauen Toolnamen nennen.

Jesper Juhl
quelle
1
Obwohl diese Tools Ihnen möglicherweise nicht zeigen, welche Funktionen möglicherweise generiert wurden (dh der Compiler durfte sie generieren, aber Sie haben diese Funktionen nie verwendet, sodass er sich entschied, sich nicht darum zu kümmern, oder die Eliminierung von Link-Time-Code hat sie beseitigt).
JMAA
@JMAA In den meisten Fällen würde "erlaubt generieren, aber nie verwendet" in Standardbegriffen bedeuten, dass eine Funktion "implizit deklariert", aber nicht "implizit definiert" wurde. Ja, dies bedeutet immer noch, dass Sie die Symbole nicht sehen, auch wenn Inlining deaktiviert ist.
Aschepler
1
Genau genommen antwortet diese Antwort genauer auf die gestellte Frage: "Welche Methoden hat der Compiler generiert?" Das ist nicht dasselbe wie die viel weniger genaue Frage "Welche Methoden könnten vom Compiler in einem anderen Kontext generiert worden sein?"
Rici
@rici Richtig. Aber die genauere Frage ist nicht leicht zu beantworten, also habe ich mich für das entschieden, was beantwortet werden könnte. Fühlen Sie sich frei, abzustimmen, wenn Sie denken, dass meine Antwort nicht wertvoll ist.
Jesper Juhl
1
@jesper: nein, ich habe bereits upvoted. Ich denke, die Frage, die Sie beantwortet haben, ist, wie gesagt, genauer. Die andere Frage, die möglicherweise beabsichtigt war, erfordert ein gewisses Handwinken, da sie kontrafaktisch ist: Wir wissen nicht, welche hypothetischen Kontexte sie enthalten könnten. Aber dies ist die Frage, die buchstäblich gestellt wird, absichtlich oder nicht, also ein großes Lob für die Beantwortung.
Rici
1

Dies ist derzeit nur eine teilweise Antwort.

Visual Studio 2019

Konstruktoren

Beim Definieren eines Klassenobjekts zeigt die IntelliSense-Funktion von Visual Studio die verfügbaren Konstruktoren an, die sowohl vom Compiler generiert als auch von Ihnen selbst erstellt wurden:

Geben Sie hier die Bildbeschreibung ein

Diese Informationen werden leider nicht immer angezeigt. Damit es für den obigen Screenshot funktioniert, musste ich etwas in Klammern eingeben, daher das Komma.

Helge Klein
quelle