Esiste un modo per scoprire automaticamente il tipo di una variabile in C, tramite un meccanismo all'interno del programma stesso o, più probabilmente, attraverso una pre-compilazione script che usa i passaggi del compilatore fino al punto in cui ha analizzato le variabili e assegnato loro i loro tipi? Sto cercando suggerimenti generali su questo. Di seguito sono riportati ulteriori dettagli su ciò di cui ho bisogno e perché.Ottenere il tipo di una variabile nel codice C
Vorrei cambiare la semantica della clausola di riduzione di OpenMP. A questo punto, sembra più semplice semplicemente sostituire la clausola nel codice sorgente (attraverso uno script) con una chiamata a una funzione, e quindi posso definire la funzione per implementare la semantica di riduzione che voglio. Per esempio, il mio script sarebbe convertire questo
#pragma omp parallel for reduction(+:x)
in questo:
my_reduction(PLUS, &x, sizeof(x));
#pragma omp parallel for
dove, in precedenza, non ho (diciamo)
enum reduction_op {PLUS, MINUS, TIMES, AND,
OR, BIT_AND, BIT_OR, BIT_XOR, /* ... */};
E my_reduction
ha firma
void my_reduction(enum reduction_op op, void * var, size_t size);
Tra gli altri t le ali, my_reduction
dovrebbero applicare l'operazione di addizione alla variabile di riduzione come originariamente previsto dal programmatore. Ma la mia funzione non può sapere come farlo correttamente. In particolare, sebbene conosca il tipo di operazione (PLUS
), la posizione della variabile originale (var
) e la dimensione del tipo di variabile, non conosce il tipo stesso della variabile. In particolare, non sa se var
ha un tipo integrale o a virgola mobile. Da un POV di basso livello, l'operazione di aggiunta per queste due classi di tipi è completamente diversa.
Se solo l'operatore non standard typeof
, supportato da GCC, funzionerebbe nel modo in cui sizeof funziona, restituendo una sorta di variabile di tipo, potrei risolvere facilmente questo problema. Ma typeof non è proprio come sizeof: può essere usato, apparentemente, solo in dichiarazioni di valore l.
Ora, il compilatore ovviamente conosce il tipo di x prima che finisca di generare il codice eseguibile. Questo mi porta a chiedermi se posso in qualche modo sfruttare il parser di GCC, solo per ottenere il tipo di x
e passarlo al mio script, e quindi eseguire nuovamente GCC, per compilare il mio codice sorgente modificato. Sarebbe quindi abbastanza semplice da dichiarare
enum var_type { INT8, UINT8, INT16, UINT16, /* ,..., */ FLOAT, DOUBLE};
void my_reduction(enum reduction_op op, void * var, enum var_type vtype);
E my_reduction
può lanciare in modo appropriato prima di dereferencing e applicando l'operatore.
Come si può vedere, sto cercando di creare una sorta di meccanismo di "invio" in C. Perché non usare solo l'overloading C++? Perché il mio progetto mi costringe a lavorare con il codice sorgente legacy scritto in C. Posso modificare il codice automaticamente con uno script, ma non riesco a riscriverlo in una lingua diversa.
Grazie!
Che ne dici del post-processing del codice sorgente con alcuni strumenti/script? Per esempio. analizzarlo con clang, trovare i tipi, inserire/regolare il codice specifico del tipo, compilare? –
Grazie, Alex. Sembra che stia andando nella giusta direzione. –
Ho letto da qualche parte che la riduzione definita dall'utente farà parte dello standard 3.1 o 4.0. Hm 3.1 dice: 'reduction ({operator | intrinsic_procedure_name}: list)' ..non ha mai provato intrinsic_procedure_name. anche se solo in parte risolve il rilevamento del tipo. – Bort