c++ compiler-errors expression declaration language-lawyer

c++ - Es tipo(:: x); ¿válido?



compiler-errors expression (2)

Esto parece ser el análisis más irritante para mí. Si se puede analizar como una declaración, será. El primero podría analizarse como una declaración de una variable int ( int ::x; ), pero :: es ilegal en ese contexto. El segundo tiene que ser una expresión y, por lo tanto, el compilador realiza los cálculos, los envía a int y descarta el resultado.

¿Fue esta una pregunta pedante, o hay otro problema también? Si tiene un problema específico que está tratando de resolver, la información adicional permitiría una solución para su caso de uso.

Mientras se discute el Type(identifier); sintaxis y cómo es una declaración, me encontré con Type(::x); no trabajando con Clang. Yo esperaría que dada una variable global x , trataría a ::x como una expresión ( ::x + 2 funciona) y cast ::x a Type . Sin embargo, da un error de compilación.

Aquí hay un pequeño ejemplo :

int x; int main() { int(::x); //does not compile int(::x + 2); //compiles }

El error de compilación proporcionado por Clang 3.5 es:

error: la definición o redeclaración de ''x'' no puede nombrar el alcance global

GCC 4.9.0, sin embargo, compila esto muy bien. ¿Este código es válido o no?


Por lo que puedo decir, esto está cubierto por el borrador de la sección estándar de C ++ 8.3 Significado de los declarantes, párrafo 6, que dice (el énfasis es mío en el futuro ):

En una declaración TD donde D tiene la forma

(D1)

el tipo del ID del declarante contenido es el mismo que el del ID del declarante contenido en la declaración

T D1

Los paréntesis no modifican el tipo de id del declarador incrustado, pero pueden alterar el enlace de los declaradores complejos.

asi que:

int(::x);

es equivalente a:

int ::x ;

que claramente no es válido, y esto produce el mismo error también. Así que gcc 4.9 no es correcto aquí, pero como parece estar fijo en el gcc 4.8.3 que se lanzó más tarde, espero que esto también se solucione en versiones posteriores de 4.9 . Aunque no veo ninguna coincidencia obvia para este problema en la lista de errores corregidos de gcc 4.8.3 , no afirman que sea una lista completa.

El segundo caso es una conversión de tipo explícita funcional que se trata en la sección 5.2.3 Conversión de tipo explícito (notación funcional) que dice:

Un especificador de tipo simple (7.1.6.2) o un especificador de nombre de tipo (14.6) seguido de una lista de expresiones entre paréntesis construye un valor del tipo especificado dada la lista de expresiones. Si la lista de expresiones es una sola expresión, la expresión de conversión de tipos es equivalente (en definición, y si se define en el significado) a la expresión de conversión correspondiente (5.4). [...]

Esto no es ambiguo ya que ::x + 2 es una expresión .

La sección que cubre cuando una declaración se considera una declaración o expresión es 6.8 Resolución de ambigüedad que dice:

Existe una ambigüedad en la gramática que involucra expresiones y declaraciones: una expresión con una conversión de tipo explícita al estilo de función (5.2.3) como su subexpresión más a la izquierda puede ser indistinguible de una declaración donde el primer declarador comienza con un (. casos, el enunciado es una declaración. [Nota: para eliminar la ambigüedad, es necesario examinar la declaración completa para determinar si es un enunciado de expresión o una declaración. Esto desambigua muchos ejemplos.

y proporciona los siguientes ejemplos:

T(a)->m = 7; // expression-statement T(a)++; // expression-statement T(a,5)<<c; // expression-statement T(*d)(int); // declaration T(e)[5]; // declaration T(f) = { 1, 2 }; // declaration T(*g)(double(3)); // declaration

Nota: sin () entonces T ::D es un id calificado en el caso de que T sea ​​una clase , eso está cubierto en la gramática de 5.1 Expresiones primarias .

Actualizar

Presentado un informe de error gcc .

La respuesta de gcc es que:

La corriente G ++ y EDG la tratan como la expresión válida (int) :: x

Dado que esta respuesta implica clang es incorrecta ( aunque no estoy de acuerdo ), archivé un informe de error de clang y el informe de error anterior es similar y parece estar en desacuerdo con la respuesta de gcc .

Actualización 2

En respuesta al clang bug report Richard Smith está de acuerdo en que esto debe tratarse como una declaración y dice:

Eso no implica que el clang sea incorrecto; de hecho, Clang es correcto aquí, hasta donde puedo ver. (También envié un informe de error a EDG).

Dicho esto, en este caso deberíamos dar un error adecuado: "aciertes a un análisis complejo, así es como desambiguar".

Actualización 3

gcc confirma que es un error.