pan skutecznie zdefiniowany h
jak:
void h(int(int)) {}
Parametr jest interpretowane jako bezimiennego wskaźnika funkcji, która pobiera int
i zwraca int
. Kiedy próbujesz przekazać do niego 42
, kompilator narzeka, że próbujesz utworzyć wskaźnik funkcji z liczby całkowitej.
Myślę, że to, o co prosisz, to w jaki sposób kompilatory obsługują (nienazwane) typy wskaźników funkcji i ich możliwie niejednoznaczne analizy. Twoje pytanie jest związane z the most vexing parse w C++.
Tam zdecydowali, że ilekroć pomiędzy typem wskaźnika funkcji i niejednoznacznym sposobem analizowania występuje niejednoznaczność, zostanie to zinterpretowane jako wskaźnik funkcji. Zrobili tak, ponieważ istnieją inne sposoby rozróżniania, gdy nie chcesz, aby był wskaźnikiem funkcji (np. - otaczaj go w nawiasach, używaj {} składni inicjalizatora, itp.).
dojazd do specyfiki jak pisarz parser może sobie z tego parsowania, oto leksykalny analizator i gramatyka dla C11: http://quut.com/c/ANSI-C-grammar-l-2011.html W przykładzie przed typedef, x
będzie IDENTIFIER
żeton natomiast później będzie to TYPEDEF_NAME
token, ponieważ analizator jest informowany za pomocą tabeli symboli, że x
jest teraz typem. W tym konkretnym przypadku parsowanie jest wtedy jednoznaczne. "Odniesienie do rurociągu", o którym zdaje się, że się powołuje, występuje w tym przypadku poprzez tabelę symboli, gdzie analizator leksykalny jest informowany o kontekście przez wyższe poziomy, które wpływają na jego wynik w miarę rozwoju kompilacji.
EDIT: Thesethreearticles, znaleziona przez PO, opisać ten problem i jak to jest rozwiązane przez niektórych parserami C/kompilatory bardzo ładnie. Zasadniczo prawie można określić gramatykę bez kontekstu, która akceptuje/generuje prawną składnię C. Po wprowadzeniu tabeli wyszukiwania o ustalonym zakresie, która pozwala analizatorowi leksykalnemu na odpowiednie rozróżnienie identyfikatorów od nazw typef, następnie CFG [i, co ważniejsze, parser LALR (1) (np. Yacc generowany)], który akceptuje/generuje tylko legalny C można podać składnię.
Oto jeszcze straszniejsze przykładem niż OP:
typedef int x;
int main() { x x = 5; return x; } /* crazily enough this is legal C syntax and a well formed C program */
Och, Fred, znowu jesteś w najbardziej irytującej analizie. Tak, to ten sam mechanizm. I masz rację, wiedza płynie z powrotem w rurociągu. –
Ktoś usunął tag C++. Odkładam to. Czy chcesz to być C lub C++ @FredOverflow. –
Lexer wysyła symbol x -> analizator składni znający znaczenie syboli znajduje potencjalne reguły gramatyczne (i ma wątpliwości, stosuje najbardziej irytującą ** parsę **) -> sprawdzian semantyczny szuka potencjalnych konwersji typów. Nie wiem, co nie powinno działać w klasycznym przewodniku ...? – Christophe