2009-10-30 16 views
13

In this SO filo, Brian Postowsuggested una soluzione che comprenda falsi funzioni anonime:funzioni anonime finto C

fare bozzetto (L) funzione che restituisce la versione di comp per matrici di lunghezza L ... così L diventa un parametro, non globale

Come si implementa tale funzione?

+0

Non credo sia necessario fornire un collegamento alla pagina principale di stackoverflow.com nella domanda. –

+0

La domanda a cui ci si collega è su come farlo in C++. Questa domanda è contrassegnata da C. Di chi vuoi sapere? –

+0

La soluzione fornita da Barry è in C. La maggior parte dei commenti suggerisce che non è possibile risolvere la mia prima domanda in C++. – Alexandru

risposta

6

Vedere the answer I just posted per quella domanda. È possibile utilizzare la libreria callback(3) per generare nuove funzioni in fase di esecuzione. Non è conforme agli standard, dal momento che comporta molti brutti attacchi specifici della piattaforma, ma funziona su un gran numero di sistemi.

La libreria si occupa dell'allocazione della memoria, assicurandosi che la memoria sia eseguibile e svuotando la cache delle istruzioni, se necessario, per garantire che il codice generato dinamicamente (ovvero la chiusura) sia eseguibile. Esso genera essenzialmente stub di codice che potrebbe essere simile a questo su x86:

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

E poi restituisce l'indirizzo della prima istruzione. Ciò che questo stub fa è memorizzare l'indirizzo di ritorno in ECX (un registro scratch nella convenzione di chiamata x86), spinge un parametro extra nello stack (un puntatore a un thunk), e quindi re-spinge l'indirizzo di ritorno. Quindi, salta alla funzione effettiva. Ciò si traduce nel fatto che la funzione viene ingannata nel pensare di avere un parametro aggiuntivo, che è il contesto nascosto della chiusura.

In realtà è più complicato di quello (la funzione di vero e proprio chiamato alla fine dello stub è __vacall_r, non la funzione stessa, e __vacall_r() gestisce più dettagli di implementazione), ma questo è il principio di base.

+0

E le prestazioni di questa soluzione? – Pacerier

1

Non è possibile generare funzioni ordinarie durante l'esecuzione in C o C++. Quello che Brian ha suggerito si basa su un grande "se": "... se riesci a simulare funzioni anonime ...". E la risposta a questo "se" è: no, non puoi. (Anche se non è chiaro cosa intendesse per "falso".)

(In C++ è possibile generare oggetti funzione simile in fase di esecuzione, ma non le funzioni ordinarie.)

Quanto sopra si applica la norma Lingue C e C++. Implementazioni particolari possono supportare varie estensioni fornite dall'implementazione e/o hack implementati manualmente, come "chiusure", "delegati" e cose simili. Nulla di ciò, ovviamente, ha nulla a che fare con i linguaggi standard C/C++.

2

Non credo che sia possibile farlo con C99 - non è disponibile alcuna funzione di chiusura o applicazione parziale a meno che non si avvii manualmente la generazione del codice macchina in fase di esecuzione.

I blocchi proposti di recente da Apple funzionerebbero, anche se per questo è necessario il supporto del compilatore. Here's a brief overview of blocks. Non ho idea di quando/se un fornitore al di fuori di Apple li supporterà.

+0

Il compilatore clang supporta Blocks, apparentemente perché Apple finanzia il progetto. – mcandre

Problemi correlati