2011-09-13 7 views
6

Sono (stavo) utilizzando i macro __FILE__ e __LINE__ per stampare i messaggi diagnostici dal mio codice. Funziona abbastanza bene quando usi GCC con make, il file è corto come lo hai specificato sulla riga di comando. Recentemente ho passato a usare CodeLite che utilizza nomi di file completi (almeno sotto Windows) durante la creazione. All'improvviso la mia uscita diagnostica non è quasi leggibile.Come ottenere solo il nome del file nel preprocessore?

C'è un modo per ottenere solo il componente file del nome file nel preprocessore? Posso vivere con una soluzione specifica GCC non portatile. (I passano a semplici __FILE__ altri casi.)

sicuro di poter passare il contenuto di __FILE__ tramite una funzione ed estrarre solo la componente del file, ma le operazioni di stringa non era quello che avevo in mente per messaggi di diagnostica che non dovrebbe cambiare comportamento di runtime ...

NOTA: Uso il nome del file nel modo in cui GNU lo utilizza. Un percorso è una raccolta di nomi di file e un nome file è un identificatore relativo o assoluto di un file. Un nome file può essere costituito da un componente di directory e un componente di file.

+0

La diagnostica modifica il comportamento in fase di esecuzione (altrimenti non ci sarebbe diagnostica), e se si chiama una funzione extra fa poca differenza, poiché l'output stesso chiama le funzioni della libreria per fare comunque l'output. – eudoxos

+0

La stampa di un messaggio diagnostico di solito comporta, oltre a dozzine di operazioni con le stringhe, alcune azioni di I/O su file non molto benigne. Per qualche motivo nessuno sembra essere preoccupato per questo. Perché preoccuparsi di aggiungere una chiamata a un'altra funzione senza effetti collaterali che interessa solo i messaggi diagnostici? –

+0

Entrambi avete ragione, aggiungere la diagnostica non è senza effetti. L'ho implementato in quel modo, l'ho lasciato passare attraverso una funzione. Mi stavo chiedendo più spesso che esista qualcosa del genere. Di certo non è standard, ma trovare documentazione su questo non è perfetto. (Anche il manuale di gcc non delinea tutte le macro predefinite.) – rioki

risposta

3

Non esiste una macro di preprocessore nota che fornisce la funzionalità. Passando __FILE__ attraverso una funzione cuciture come l'unica opzione ragionevole.

+0

Per gcc c'è [\ _ \ _ BASE_FILE \ _ \ _] (https://gcc.gnu.org/onlinedocs/cpp/Common-Predefined-Macros.html). – fret

+1

@fret: per me, '__BASE_FILE__' restituisce lo stesso di' __FILE__'. Se leggi la documentazione a cui sei collegato, fornisce il nome (non necessariamente basename) del file con la funzione 'main' (non il file corrente, anche). – JellicleCat

+1

@JellicleCat hai ragione ... – fret

8

Se si utilizza GNU Make, è possibile passare semplicemente -D BASE_FILE_NAME = \ "$ *. C \" nella fase di pre-elaborazione della compilazione (se le si sta facendo separatamente o alla compilazione se in una singola fase, che è la norma).

Questo dipende dal modo in cui sono determinati i nomi dei file. I miei provengono da una lista di semplici nomi di file e sono preceduti da directory che usano funzioni nel makefile in una fase successiva.

IE, questo funziona bene per me, ma il tuo chilometraggio può variare! :-)

Una versione semplificata del mio make "codice":

CLASSES = main.c init.c 

PREPROCESSED = $(patsubst %.c,$(PPCDIR)/%.pp.c,$(CLASSES)) 

$(PREPROCESSED): $(PPCDIR)/%.pp.c: %.c $(ALLH) 
    $(GCC) $(GCCOPTS) -D BASE_FILE_NAME=\"$*\" -E $< > [email protected] 

Il BASE_FILE_NAME semplicemente utilizzare nel codice come ti piace :-)

+0

Purtroppo sto lavorando con CodeLite, che genera i makefile per me. Usare CodeLite è fantastico, finché non vuoi fare qualcosa che non rientra nella norma. Ancora bella idea, +1 – rioki

+0

La stessa idea può essere utilizzata in Visual Studio. In Visual Studio 2008: fare clic con il pulsante destro del mouse sul file di progetto (.vcproj) -> Proprietà -> Proprietà di configurazione -> C/C++ -> Preprocessore -> Definizioni del preprocessore. Aggiungi __BASE_FILE __ = \ "$ (InputFileName) \". Puoi usare __BASE_FILE__ invece di __FILE__ nei tuoi file sorgente. – user720594

4

In risposta a FredCooke sopra, è possibile scambiare questa linea:

-D BASE_FILE_NAME=\"$*.c\" 

Con:

-D BASE_FILE_NAME=\"$(<F)\" 

Questo ti darà la corretta espansione del nome del file, anche per .cpp.