2009-10-30 13 views
13

W this SO wątku, Brian Postowsuggested rozwiązania obejmującego fałszywych anonimowych funkcje:Sztuczne anonimowych funkcje C

aby zarys (L) funkcję, która zwraca wersję COMP tablice długości L ... w ten sposób L staje się parametrem, a nie globalnym

Jak mogę wdrożyć taką funkcję?

+0

Nie sądzę, że konieczne jest podanie linku do strony głównej stackoverflow.com w pytaniu. –

+0

Pytanie, które łączysz, dotyczy tego, jak to zrobić w C++. To pytanie jest oznaczone C. Którego chcesz się dowiedzieć? –

+0

Rozwiązanie przedstawione przez Barry znajduje się w C. Większość komentarzy sugeruje, że nie jest możliwe rozwiązanie mojego pierwszego pytania w C++. – Alexandru

Odpowiedz

6

Zobacz the answer I just posted na to pytanie. Możesz użyć biblioteki callback(3), aby wygenerować nowe funkcje w środowisku wykonawczym. Nie jest to zgodne ze standardami, ponieważ zawiera wiele brzydkich, specyficznych dla platformy hacków, ale działa na wielu systemach.

Biblioteka zajmuje się przydzielaniem pamięci, upewniając się, że pamięć jest wykonywalna i czyści pamięć podręczną instrukcji, jeśli jest to konieczne, w celu zapewnienia, że ​​kod, który jest generowany dynamicznie (tj. Zamknięcie), jest wykonywalny. Zasadniczo generuje kody kodu, które mogą wyglądać tak na x86:

pop %ecx 
    push $THUNK 
    push %ecx 
    jmp $function 
THUNK: 
    .long $parameter 

Następnie zwraca adres pierwszej instrukcji. To, co robi ten kod pośredniczący, zapisuje adres powrotu do ECX (rejestru zdrapek w konwencji wywoływania x86), przesuwa dodatkowy parametr na stos (wskaźnik do thunk), a następnie ponownie przesyła adres zwrotny. Następnie przechodzi do rzeczywistej funkcji. Powoduje to, że funkcja zaczyna się oszukiwać, myśląc, że ma dodatkowy parametr, który jest ukrytym kontekstem zamknięcia.

Jest to faktycznie bardziej skomplikowane (rzeczywistą funkcją wywoływaną na końcu kodu pośredniczącego jest __vacall_r, a nie sama funkcja, a __vacall_r() obsługuje więcej szczegółów implementacji), ale to jest podstawowa zasada.

+0

Co z wydajnością tego rozwiązania? – Pacerier

1

Nie jest możliwe generowanie zwykłych funkcji podczas wykonywania w C lub C++. To, co zasugerował Brian, jest oparte na dużym "jeśli": "... jeśli możesz sfałszować anonimowe funkcje ...". A odpowiedź na to "jeśli" brzmi: nie, nie możesz. (Choć nie jest jasne, co miał na myśli „fake”).

(W C++ możliwe jest generowanie obiektów funkcyjnych, jak w czasie wykonywania, ale nie zwykłe funkcje.)

Powyższe dotyczy norma Języki C i C++. Poszczególne implementacje mogą obsługiwać różne implementowane rozszerzenia i/lub ręcznie implementowane hacki, takie jak "zamknięcia", "delegaty" i podobne rzeczy. Nic z tego oczywiście nie ma nic wspólnego ze standardowymi językami C/C++.

2

Nie wierzę, że można to zrobić za pomocą C99 - nie ma dostępnej częściowej aplikacji ani narzędzia zamknięcia, chyba że ręcznie wygenerujesz kod urządzenia w czasie wykonywania.

Ostatnio zaproponowane bloki Apple działałyby, chociaż potrzebujesz wsparcia kompilatora. Here's a brief overview of blocks. Nie mam pojęcia, kiedy/jeśli jakiś dostawca spoza Apple będzie je wspierać.

+0

Kompilator clang obsługuje Bloki, najwyraźniej dlatego, że Apple finansuje projekt. – mcandre

Powiązane problemy