Je manque certainement quelque chose, mais je ne comprends pas pourquoi cela se compile (avec à la fois g ++ et clang ++):
struct A
{
};
struct B
{
};
int main()
{
A a(B);
}
Tout d'abord, B
c'est un type ... pas une valeur. Comment dois-je interpréter ce code?
c++
syntax
declaration
most-vexing-parse
Picaud Vincent
la source
la source
A a(B());
ce qui pourrait être une définition de variable ou une déclaration de fonction.struct A{}; int main() { A(foo); }
compile tel quel , même s'ilfoo
ne nomme rien.Réponses:
Il est interprété comme la déclaration d'une fonction nommée
a
, qui prend un argument de typeB
et retourneA
.la source
A a{B};
Il s'agit simplement d'une déclaration de fonction déclarant
a
être une fonction renvoyantA
et prenant un paramètre de type sans nomB
.Il est valide car les déclarations de fonction, par opposition aux définitions de fonction, sont autorisées dans les définitions de fonction.
la source
Ce problème est connu comme l' analyse la plus contrariante . La ligne
A a(B);
peut être interprétée comme la déclaration d'une fonction nomméea
renvoyant un objet de typeA
et prenant un paramètre de type sans nomB
.Une façon d'éviter ce problème est d'utiliser la syntaxe d' initialisation uniforme introduite en C ++ 11, qui consiste à utiliser des accolades à la place des parenthèses:
A a{B};
renvoie une erreur. La ligne est maintenant interprétée comme une déclaration de variable initialisée avecB
, qui est un type au lieu d'une valeur.Voici plus d'informations:
L'analyse la plus contrariante: comment la repérer et la corriger rapidement
la source
struct A { };
ne sont pas valides en C standard, même si certains compilateurs le permettent. Laissez tomber les accolades et il n'y aurait pas de problème là-bas. De plus, en C, déclarer ou définirstruct A
ne crée pas de nom de typeA
(vous devez le préfixer avecstruct
, ou ajoutertypedef struct A A;
quelque part avantA
est utilisé sans lestruct
préfixe). Toujours en C, il n'y a pas d'analyse alternative à la déclaration de fonction - l'utilisationtype name(...);
ne peut tout simplement jamais être une définition de variable; c'est toujours une déclaration de fonction (ou invalide). Le code dans la question n'est pas valide en C.