2014-10-31 6 views
8

Dieser CodeInteraktion zwischen decltype und Klassenelementname einen externen Namen

int clash; 

struct Foo { 
    decltype(clash) clash; 
}; 

kompiliert still auf Klirren Shadowing, aber nicht auf gcc geben die Fehler

error: declaration of 'int Foo::clash' [-fpermissive]

error: changes meaning of 'clash' from 'int clash' [-fpermissive]

Es scheint, dass zwei Zutaten zu kompilieren sind erforderlich, damit der Fehler auftritt:

  1. Die Spiegelung muss von einem Klassenmitglied durchgeführt werden (kein Problem, wenn es der lokale Bereich einer Funktion ist).

  2. decltype ([schattierter Name]) muss im Shadowing-Bereich vor der Deklaration von [Shadowing Name] verwendet werden.

Meine Frage ist zweifach:

  1. gcc gerechtfertigt ist in dieser Code Ablehnung?
  2. Wo sagt es so in der Norm?
+0

Worum geht es: 'int chash [sizeof (clash)];'? Was sagt der Compiler? Ich denke, es geht nicht um C++ 11-Compiler, sondern darum, wie sie sich in solchen Fällen verhalten. – Ajay

Antwort

9

gcc korrekt ist das Programm schlecht ausgebildet, obwohl diese spezielle Verletzung erfordert nicht ein diagnostisches so clang nicht eins zu bieten hat.

Wenn wir an dem C++ 11-Standard aussehen (Der nächste Entwurf wäre N3337) Abschnitt 3.3.7Klasse Umfang heißt es:

A name N used in a class S shall refer to the same declaration in its context and when re-evaluated in the completed scope of S. No diagnostic is required for a violation of this rule.

und die nächste Regel sagt:

If reordering member declarations in a class yields an alternate valid program under (1) and (2), the program is ill-formed, no diagnostic is required.

Es ist sinnvoll, dass wir Situationen vermeiden möchten, in denen das Umordnen der Deklarationen in einer Klasse ein anderes Programm ergibt. Es ist gespannt, ob these two rules are redundant or not.

Der Abschnitt enthält auch das folgende Beispiel:

enum { i = 1 }; 

class X { 
    char v[i]; // error: i refers to ::i 
      // but when reevaluated is X::i 
    int f() { return sizeof(c); } // OK: X::c 
    char c; 
    enum { i = 2 }; 
}; 

und wenn wir dieses Beispiel mit gcc (see it live) versuchen, erhalten wir ein fast identischen Fehler einen Code erzeugt:

error: declaration of 'i' [-fpermissive] 
enum { i = 2 }; 
     ^

error: changes meaning of 'i' from '<anonymous enum> i' [-fpermissive] 
enum { i = 1 }; 
+0

Sie zitierten einen _draft_, was wenig bedeutet. Ich zeige Ihnen, wie man den aktuellen Standard zitiert, der maßgebend ist. –

+4

Die Entwürfe "wenig Bedeutung" ist nicht .. * ganz * wahr. Ihre vollständige Bezeichnung ist "Standard ** Working ** Draft" und als solche sind sie ein bisschen mehr als "nur ein Entwurf". Betrachtet man [diese Frage] (http://stackoverflow.com/questions/14184203/changes-between-c-standard-working-drafts), ist es klar, dass sie allmählich verfeinert werden. – usr2564301

Verwandte Themen