2010-07-05 13 views
15

voglio definire una macro che include un altro file di intestazione in questo modo:Utilizzando #define per includere un altro file in C++/C

#define MY_MACRO (text) #include "__FILE__##_inline.inl" 

modo che quando il preprocessore analizza file di Person.h, MY_MACRO (blahblah) si espande per

#include "person.h.inline.inl"

eventuali suggerimenti su come fare questo?

+2

Non è possibile. – Philipp

risposta

14

Non è possibile utilizzare #define per costruire altre direttive del preprocessore, a meno che non si esegua il preprocessore due volte.

Ma nel tuo caso anche il funzionamento del preprocessore due volte non aiuta perché il #include deve essere una stringa singola del modulo "..." o <...>.

+1

Questo è falso, ho lavorato con il codice che ha fatto questo. Hanno incluso il file più volte, ogni volta ridefinendo la macro prima di includerla. Ciò ha causato l'esecuzione delle macro più volte, una volta per inclusione. Il caso d'uso che ho visto era puro codice C che utilizzava questo trucco per creare pseudo-modelli. –

+0

@GabeSechan Quello che hai descritto è comunemente chiamato X Macro. Ma non esegue il preprocessore più volte. Ridefinisce le macro e include i file più volte. È un trucco davvero interessante per alcuni casi d'uso. – woodtluk

3

Non è possibile scrivere altre direttive di pre-processore utilizzando il pre-processore. Tuttavia, credo che si potrebbe definire semplicemente il nome del file:

#define MY_MACRO(name) "__FILE__##name_inline.inl" 

#include MY_MACRO(name) 

Il pre-processore esegue più volte fino a quando non ci sono ulteriori sostituzioni si può fare, quindi dovrebbe espandere il nome e poi # include il file di riferimento .

EDIT: Ho appena provato e il pre-processore non può gestire le citazioni del genere.

#define MY_MACRO(x) <__FILE__##x_inline.inl> 
#include MY_MACRO(foo) 

funziona bene, ma <> non può essere quello che si voleva.

EDIT2: come indicato da sth nei commenti, lo __FILE__ non si espande correttamente, il che rende questo probabilmente non ciò che si desidera dopo tutto. Scusate.

+1

http://codepad.org/AxNh2h3F Apparentemente '" __FILE __ ## nome_inline.inl "' è trattato letteralmente, ma se lo si passa a '#define MY_MACRO (nome) <__ FILE__ ## nome ## _inline.inl>' quindi * puoi * includere effettivamente un file in modo variabile. –

+0

Non penso che funzioni affatto. La macro fornita si espande in '<__ FILE__x_inline.inl>', mentre dovrebbe essere qualcosa come ''. – sth

+0

@sth: hai ragione, l'ho perso. Ho provato scomponendola a due fasi così: [code] #define MY_MACRO (a) __FILE__ ## un #define MY_MACRO_2 (b) #include MY_MACRO_2 (test) [/ code] ma questo non aiuta neanche. – Vicky

9

Non è possibile utilizzare __FILE__ perché è già quotato e #include non supporta la concatenazione di stringhe. Ma è possibile utilizzare le macro dopo #include:

#define STRINGIZE_AUX(a) #a 
#define STRINGIZE(a) STRINGIZE_AUX(a) 
#define CAT_AUX(a, b) a##b 
#define CAT(a, b) CAT_AUX(a, b) 
#define MY_MACRO(file, name) STRINGIZE(CAT(file, CAT(name, _inline.inl))) 
#include MY_MACRO(aaaa, qqq) 

si dovrebbe usare le macro Boost.Preprocessor equivalenti al posto di CAT e STRINGIZE per impedire l'inquinamento namespace globale.

+0

+1 Non sono sicuro che sia molto brutto o molto bello ma sembra funzionare ... – Tomas

+0

sì, riesce a includere il file, ma devo ancora usare un #include separato, e sembra anche che __FILE__ sia esteso a una stringa quotata, quindi potrebbe essere impossibile. –

+0

Sì, è davvero impossibile. Prova a riprogettare la tua applicazione in modo che non sia necessaria. – Philipp

-5
#if 0 /*Windows*/ 
#define MKDIR_ENABLER <direct.h> 
#define MY_MKDIR(x,y) _mkdir((x)) 
#else /*Linux*/ 
#define MKDIR_ENABLER <sys/stat.h> 
#define MY_MKDIR(x,y) mkdir((x),(y)) 
#endif 

#include MKDIR_ENABLER 

int main(void) 
{ 
    MY_MKDIR("more_bla",0644); 
    return 0; 
} 

Questo codice include il file di intestazione appropriato per mkdir (perché è diverso su UNIX e Windows) e introduce una bella wrapper per esso.

+0

E in che modo questo fornisce una risposta? – dhein

Problemi correlati