c++ gcc scope language-lawyer decltype

c++ - Interacción entre decltype y nombre de miembro de clase que sombrea un nombre externo



gcc scope (1)

gcc es correcto, el programa está mal formado, aunque esta violación en particular no requiere un diagnóstico, por lo que no es necesario que clang proporcione uno.

Si miramos el estándar C ++ 11 ( El borrador más cercano sería N3337 ), sección 3.3.7 Alcance de la clase , dice:

Un nombre N usado en una clase S se referirá a la misma declaración en su contexto y cuando se reevalúe en el alcance completo de S. No se requiere diagnóstico para una violación de esta regla.

y la siguiente regla dice:

Si reordenar las declaraciones de miembros en una clase produce un programa válido alternativo bajo (1) y (2), el programa está mal formado, no se requiere diagnóstico.

Tiene sentido que deseemos evitar situaciones en las que reordenar las declaraciones en una clase proporcione un programa diferente. Es curioso si estas dos reglas son redundantes o no .

La sección también proporciona el siguiente ejemplo:

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

y si probamos este ejemplo con gcc ( verlo en vivo ), obtenemos un error casi idéntico al que produce su código:

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

Este código

int clash; struct Foo { decltype(clash) clash; };

se compila silenciosamente en el sonido metálico, pero no se compila en gcc dando los errores

error: declaración de ''int Foo :: clash'' [-fpermissive]

error: cambia el significado de ''clash'' de ''int clash'' [-fpermissive]

Parece que se requieren 2 ingredientes para que surja el error:

  1. El sombreado debe ser realizado por un miembro de la clase (no hay problema si es el alcance local de una función).

  2. decltype ([nombre sombreado]) debe usarse en el ámbito de sombreado antes de la declaración de [nombre sombreado].

Mi pregunta es doble:

  1. ¿Se justifica gcc al rechazar este código?
  2. ¿Dónde lo dice en el estándar?