2015-01-08 19 views
11

Say a un colpo di testa, che io non voglio leggere me stesso, ma che io includere, hoCome ottenere la definizione di una macro come stringa letterale?

#define A B 
#define B C 

Ora

#define STR(name) # name 

definisce una macro che mi dà il nome di qualsiasi macro come una stringa e

#define EXP_STR(name) STR(name) 

definisce una macro che mi dà l'espansione completa di qualsiasi macro come stringa. Quindi

cout << STR(A) << EXP_STR(A) << endl; 

stampa AC.

C'è un modo per ottenere "B" da A utilizzando alcuni macro?

+2

Non sono sicuro. Credo che questo non sia possibile a causa di come l'espansione del token in C funziona. Questa è un'ottima domanda. – fuz

+0

È una domanda eccellente, ma sono quasi sicuro che ciò non sia possibile, spero che qualcuno sappia se lo è, e se non è una buona spiegazione. –

+2

possibile duplicato di [Evitare una doppia sottomissione della macro nel pre-processore C] (http://stackoverflow.com/questions/27533994/avoiding-a-double-macro-subsitution-in-the-c-pre-processore) – this

risposta

1

Dal momento che è possibile scrivere

#define B C 
#define A B 

#define STR(name) # name 
#define EXP_STR(name) STR(name) 

e la

cout << STR(A) << EXP_STR(A) << endl; 

uscita volontà exaclty lo stesso, significa che non è possibile.

Quando si esegue questa

#define A B 

e poi

#define B C 

ora ciò significa che A sarà sostituito da C e non B, quindi non ci sarà modo di farlo perché quando il cout linea è stato raggiunto il preprocessore aveva già sostituito A per C.

Quindi la risposta breve è, non è possibile perché il preprocessore avrebbe sostituito A con C prima che il file viene compilato.

+0

Si noti che la riga '#define AB' fa ** non ** definisce A come C, solo perché B è definito come C. Se faccio' #undef B', '#define BX', e poi' cout << STR (A) << "" << EXP_STR (A) << endl; ', l'uscita sarà AX. L'espansione viene eseguita quando la macro viene "chiamata" non quando viene definita. Alcune lingue ([make] (https://www.gnu.org/software/make/manual/html_node/Flavors.html)) non possono nemmeno decidere autonomamente in che modo farlo. –

+0

@ not-a-user Ho postato la mia risposta prima di vedere il tuo commento, ma fornisco un bel modo per farlo ... –

0

Sì, è possibile. Devi solo usare un paio di cheat.

  • #undef B prima #define EXP_STR
  • utilizzare un paio di livelli di indirezione

Ad esempio:

#define A B 
#define B C 

#define _TEMP_VAR B // so that it can be redefined later 
#undef B    // so that EXP_STR(A) will return "B" 

#define EXP_STR__(x) (x) 
#define EXP_STR_(x) EXP_STR__(#x) 
#define EXP_STR(x) EXP_STR_(x) 

#define STR(x) # x 

#define B _TEMP_VAR // now you can still access A normally, defined to B (defined to C) 

Un programma di test per dimostrarlo:

#include <stdio.h> 

int main(void) 
{ 
    printf("EXP_STR(A) = %s\n", EXP_STR(A)); 
    printf("STR(A)  = %s\n", STR(A)); 
} 

Uscita:

EXP_STR(A) = B 
STR(A)  = A 
+0

Potresti chiarire un po 'questo? Dobbiamo fare tutto questo codice per ogni macro che vogliamo essere in grado di stampare? O solo una volta? – Vality

+0

@Vality Definisci i macro su cui vuoi usare 'EXP_STR' prima di' #define _TEMP_VAR'. –

+0

Grazie, ingrandito. – Vality

Problemi correlati