Z pewnością czegoś brakuje, ale nie rozumiem, dlaczego to się kompiluje (zarówno z g ++, jak i clang ++):
struct A
{
};
struct B
{
};
int main()
{
A a(B);
}
Przede wszystkim B
jest typem ... a nie wartością. Jak mam interpretować ten kod?
c++
syntax
declaration
most-vexing-parse
Picaud Vincent
źródło
źródło
A a(B());
to definicja zmiennej lub deklaracja funkcji.struct A{}; int main() { A(foo); }
kompiluje się w obecnej postaci , nawet jeślifoo
niczego nie wymienia.Odpowiedzi:
Jest interpretowany jako deklaracja o nazwie funkcja
a
, która pobiera jeden argument typuB
i zwracaA
.źródło
A a{B};
Jest to po prostu deklaracja funkcji, która deklaruje,
a
że jest funkcją zwracającąA
i przyjmującą jeden nienazwany parametr typuB
.Jest poprawny, ponieważ deklaracje funkcji, w przeciwieństwie do definicji funkcji, są dozwolone w definicjach funkcji.
źródło
Ten problem jest znany jako najbardziej dokuczliwa analiza . Linia
A a(B);
może być interpretowana jako deklaracja funkcji o nazwiea
zwracającej obiekt typuA
i przyjmującej nienazwany parametr typuB
.Jednym ze sposobów uniknięcia tego problemu jest użycie jednolitej składni inicjalizacji, która została wprowadzona w C ++ 11, która polega na użyciu nawiasów klamrowych zamiast nawiasów:
A a{B};
zwraca błąd. Linia jest teraz interpretowana jako inicjalizacja deklaracji zmiennejB
, która jest typem zamiast wartości.Oto więcej informacji:
Najbardziej zwariowana analiza: jak ją zlokalizować i szybko naprawić
źródło
struct A { };
nie są poprawne w standardowym C, nawet jeśli niektóre kompilatory na to pozwalają. Upuść szelki, a tam nie będzie problemu. Również w C deklarowanie lub definiowaniestruct A
nie tworzy nazwy typuA
(musisz ją poprzedzićstruct
lub dodaćtypedef struct A A;
gdzieś przedA
użyciem bezstruct
prefiksu). Również w C nie ma alternatywnej analizy względem deklaracji funkcji - użycietype name(...);
po prostu nigdy nie może być definicją zmiennej; zawsze jest to deklaracja funkcji (lub niepoprawna). Kod w pytaniu jest nieprawidłowy w C.