¿Una statement que utiliza “auto” coincide con una statement externa que utiliza un especificador de tipo concreto?

Considere el siguiente progtwig:

extern int x; auto x = 42; int main() { } 

Clang 3.5 lo acepta ( demostración en vivo ), GCC 4.9 y VS2013 no ( demostración en vivo para el primero ). ¿Quién tiene razón y dónde se especifica el comportamiento correcto en el Estándar C ++?

Hay sorprendentemente poco en el estándar sobre esto. Sobre todo lo que escuchamos sobre la restatement es:

[C++11: 3.1/1]: una statement (cláusula 7) puede introducir uno o más nombres en una unidad de traducción o redeclarar nombres introducidos por declaraciones anteriores. [..]

y la única parte relevante de la semántica del auto :

[C++11: 7.1.6.4/3]: De lo contrario, el tipo de la variable se deduce de su inicializador. [..]

(recordándonos que el tipo de x es int ).

Sabemos que una variable debe recibir el mismo tipo en todas las declaraciones:

[C++11: 3.5/10]: después de todos los ajustes de tipos (durante los cuales los typedefs (7.1.3) son reemplazados por sus definiciones), los tipos especificados por todas las declaraciones referentes a una variable o función dada serán idénticos , excepto que las declaraciones para un objeto de matriz pueden especificar tipos de matriz que difieren por la presencia o ausencia de una matriz principal encuadernada (8.3.4). Una violación de esta regla sobre la identidad de tipo no requiere un diagnóstico.

y el “después de todos los ajustes de tipos” debe encargarse de cualquier pregunta con respecto a la participación del auto en todo esto; mi interpretación, entonces, es que esto es intrínsecamente una restatement (y definición) válida de la x en el ámbito global con tipo int , y que Clang es correcta . Incluso si proponemos que auto no cuenta como “ajuste de tipo”, ya que no se requiere diagnóstico, en el peor de los casos todas las implementaciones enumeradas son compatibles a su manera.

Creo que GCC y Visual Studio están tomando lo siguiente como inspiración:

[C++11: 7.1.6.4/5]: Un progtwig que usa auto en un contexto no explícitamente permitido en esta sección está mal formado.

… pero creo que esto es miope. Parece poco probable que el lenguaje estándar esté destinado a prohibir las reglas de restatement usuales, simplemente porque no se repiten o se hace referencia explícita desde 7.1.6.4 .

C ++ 14 agrega texto que se relaciona con declaraciones de funciones con tipos deducidos:

[C++14: 7.1.6.4/13]: redeclaraciones o especializaciones de una función o plantilla de función con un tipo de retorno declarado que utiliza un tipo de marcador de posición también deben usar ese marcador de posición, no un tipo deducido. [..]

Por simetría uno podría sugerir que, en su caso int , se pretende que GCC y VS sean correctos al rechazar el progtwig. Sin embargo, esta es una característica diferente (ya que la deducción no se puede aplicar a meras declaraciones) y, por lo tanto, un escenario diferente.

De cualquier manera, la redacción estándar mejorada ayudaría aquí. Lo considero un defecto editorial [razonablemente menor].