Ciertamente me falta algo, pero no entiendo por qué esto se compila (con g ++ y clang ++):
struct A
{
};
struct B
{
};
int main()
{
A a(B);
}
En primer lugar, B
es un tipo ... no un valor. ¿Cómo debo interpretar este código?
c++
syntax
declaration
most-vexing-parse
Picaud Vincent
fuente
fuente
A a(B());
que podría ser una definición variable o una declaración de función.struct A{}; int main() { A(foo); }
compila tal cual , incluso sifoo
no nombra nada.Respuestas:
Se interpreta como la declaración de una función denominada
a
, que toma un argumento de tipoB
y devuelveA
.fuente
A a{B};
Es simplemente una declaración de función que declara
a
ser una función que regresaA
y toma un parámetro de tipo sin nombreB
.Es válido porque las declaraciones de función en lugar de las definiciones de función están permitidas dentro de las definiciones de función.
fuente
Este problema se conoce como el análisis más irritante . La línea
A a(B);
se puede interpretar como la declaración de una función llamada quea
devuelve un objeto de tipoA
y toma un parámetro de tipo sin nombreB
.Una forma de evitar este problema es usar la sintaxis de inicialización uniforme que se introdujo en C ++ 11, que consiste en usar llaves en lugar de paréntesis:
A a{B};
devuelve un error. La línea ahora se interpreta como una declaración de variable inicializada conB
, que es un tipo en lugar de un valor.Aquí hay más información:
El análisis más irritante: cómo detectarlo y solucionarlo rápidamente
fuente
struct A { };
no son válidas en el estándar C, incluso si algunos compiladores lo permiten. Suelta los frenos y no habría problema allí. Además, en C, declarar o definirstruct A
no crea un nombre de tipoA
(debestruct
agregarle el prefijo o agregarlo entypedef struct A A;
algún lugar antes deA
usarlo sin elstruct
prefijo). También en C, no hay un análisis alternativo a la declaración de función: el usotype name(...);
simplemente no puede ser una definición variable; siempre es una declaración de función (o no válida). El código en la pregunta no es válido en C.