2015-12-22 7 views
12

ich gerade herausgefunden, dass der folgende Code keine gültigen C++ (es int nach ~ analysiert nicht):Ist es legal, einen Destruktor auf int32_t aufzurufen?

int x = 5; 
x.~int(); 

Allerdings ist der folgende Ausschnitt Arbeit:

int32_t x = 5; 
x.~int32_t(); 

Dies liegt daran, int32_t ist ein typedef in meiner bestimmten Implementierung von C++, und ein Destruktor kann anscheinend auf jedem typendefinierten Typ aufgerufen werden.

Meine Frage ist: ist eine Implementierung von C++ erforderlich, um das zweite Snipped zu kompilieren? Insbesondere ist int32_t garantiert, ein typedef zu sein, und ist der Compiler erforderlich, um eine Zerstörung eines typedef zuzulassen, wenn es typedef typedefs etwas zu int kennt?

+0

Ja. 'int32_t' ist kein eingebauter Typ und es darf kein Makro sein. –

+0

@ Cheersandhth.-Alf Der C++ 14-Standardentwurfsstatement 'typedef signed integer type int32_t;' als Definition von 'int32_t'. Soweit ich das beurteilen kann, bleibt nicht viel Platz für benutzerdefinierte Typen und alle oder gar ein Makro. – Downvoter

+0

Um eine enge Frage/offenen Frage Krieg zu vermeiden, werde ich nicht wählen, um als Duplikat zu schließen, aber ... das ist ein Duplikat der verknüpften Frage. Nur weil diese andere Frage "int32_t" nicht erwähnt, heißt das nicht, dass diese andere Frage nicht auf Ihre Antwort antwortet. –

Antwort

8

Es gibt eine klare Anforderung, dass int32_t ein Typdef sein soll. Wir beginnen mit [cstdint.syn]/2:

Der Header definiert alle Funktionen, Typen und Makros wie 7.18 im C-Standard.

So von dort aus betrachten wir die Voraussetzung für die C-Bibliothek:

Der typedef Name intN_t bezeichnet einen signierten Integer-Typ mit einer Breite N, ohne Füllbits und eine Zweierkomplement-Darstellung.

[Hervorhebung hinzugefügt]

Also ja, int32_t muss ein "typedef Name" sein.

Obwohl (soweit ich weiß) es niemals direkt in normativen Texten angegeben ist, macht der folgende Hinweis deutlich, dass das Aufrufen eines Destruktors für einen typedef, der in einen eingebauten Typ aufgelöst wird, kompiliert und gelingen soll ([class .dtor]/16):

Hinweis: Die Schreibweise für den expliziten Aufruf eines Destruktors kann für jeden Skalartypnamen (5.2.4) verwendet werden. Wenn Sie dies zulassen, können Sie Code schreiben, ohne zu wissen, ob ein Destruktor für einen bestimmten Typ existiert. Zum Beispiel

typedef int I; 
I* p; 
p->I::~I(); 
+0

Das Snippet ist natürlich undefiniertes Verhalten (Mitglied Zugriff über einen wilden Zeiger).Oder garantiert der Standard, dass die Verwendung dieser Syntax für ein Primitiv ein No-Op ist und der Mitgliederzugriff niemals stattfindet? –

+0

@BenVoigt: Gute Frage. Ich denke nicht, dass der Zeiger tatsächlich dereferenziert werden sollte, aber ich bin mir nicht sicher, ob ich eine Aussage finden kann, die das mit Sicherheit sagt. –

+0

"Der einzige Effekt ist die Auswertung des Postfix-Ausdrucks vor dem Punkt oder Pfeil." (5.2.4) Also dann '(* p) .I :: ~ I()' schlecht aber 'p-> I :: ~ I()' gut? Und es ist eigentlich egal, was der Typ ist? Scheint wie ein Defekt. –

Verwandte Themen