2014-10-31 10 views
8

Questo codiceInterazione tra decltype e il nome del membro della classe shadowing un nome esterno

int clash; 

struct Foo { 
    decltype(clash) clash; 
}; 

compila in silenzio su clang, ma non riesce a compilare su gcc dà errori

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

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

Sembra che 2 ingredienti sono richiesto per l'errore:

  1. L'ombreggiamento deve essere eseguito da un membro della classe (nessun problema se è lo scope locale di una funzione).

  2. decltype ([nome ombreggiato]) deve essere utilizzato nell'ombreggiamento prima della dichiarazione di [nome ombreggiatura].

La mia domanda è duplice:

  1. è GCC giustificato nel respingere questo codice?
  2. Dove lo dice nello standard?
+0

Che dire: 'int chash [sizeof (clash)];'? Cosa dice un compilatore diverso? Immagino che non abbia a che fare con i compilatori di reclami C++ 11, ma come si comportano in questi casi. – Ajay

risposta

9

gcc è corretto il programma è mal formato, anche se questo particolare violazione non richiede una diagnosi in modo clang non deve fornire uno.

Se guardiamo lo standard C++ 11 (Il progetto più vicino sarebbe N3337) sezione 3.3.7Classe portata dice:

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.

e la regola successiva dice:

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.

È logico che desideriamo evitare situazioni in cui il riordino delle dichiarazioni in una classe fornisce un programma diverso. È curioso se these two rules are redundant or not.

La sezione fornisce anche il seguente esempio:

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 }; 
}; 

e se cerchiamo questo esempio con gcc (see it live), otteniamo un errore quasi identico ad uno il codice produce:

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

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

Hai citato un _draft_, che significa poco. Ti sto mostrando come citare lo standard attuale, che è autorevole. –

+4

Le bozze "significato poco" non sono .. * interamente * vero. La loro designazione completa è "Standard ** Working ** Draft", e come tali sono un po 'più di' solo una bozza '. Guardando [questa domanda] (http://stackoverflow.com/questions/14184203/changes-between-c-standard-working-drafts), è chiaro che vengono affinati gradualmente. – usr2564301

Problemi correlati