23

ho una macro di preprocessore definito in impostazioni di generazionepreprocessore macro valore alla stringa di Objective-C letterale

FOO=BAR 

Tale valore voglio massaggiare in una stringa Objective-C letterale che può essere passato a un metodo. Il seguente #define non funziona, ma dovrebbe dare prova di quello che sto cercando di realizzare:

#define FOOLITERAL @"FOO" //want FOOLITERAL to have the value of @"BAR" 

myMethodThatTakesAnNSString(FOOLITERAL); 

mi aspetto che io sono solo manca l'ovvio in qualche modo, ma io non riesco a trovare il giusto voodoo preprocessore per ottenere ciò che Ho bisogno.

risposta

32

Utilizzare l'operatore stringizing# per fare una stringa C fuori del simbolo. Tuttavia, a causa di un capriccio del preprocessore, è necessario utilizzare due strati aggiuntivi di macro:

#define FOO BAR 
#define STRINGIZE(x) #x 
#define STRINGIZE2(x) STRINGIZE(x) 
#define FOOLITERAL @ STRINGIZE2(FOO) 
// FOOLITERAL now expands to @"BAR" 

La ragione per gli strati più è che l'operatore stringizing può essere utilizzato solo sugli argomenti della macro, non su altri token. In secondo luogo, se un argomento di una macro ha applicato l'operatore di stringa nel corpo della macro, tale argomento è non espanso come un'altra macro. Pertanto, per garantire che FOO venga espanso, eseguiamo il wrapping in un'altra macro, in modo che quando STRINGIZE2 viene espansa, si espande anche FOO perché l'operatore di stringa non viene visualizzato nel corpo di quella macro.

+0

Questo l'ha fatto. Avevo provato il double indirection, ma avevo anche il valore "@" come valore macro e questo sembra confonderlo. Una piccola differenza è che la prima linea non rappresenta il mio caso in quanto non recupera l'impostazione accumulo #define FOO FOOVAL #define STRINGIZE (x) #x #define STRINGIZE2 (x) STRINGIZE (x) #define FOOLITERAL @ STRINGIZE2 (FOOVAL) è ciò che effettivamente funziona per me. Ma la tua risposta mi ha portato lì. – vagrant

+0

Ciao @vagrant. Questa soluzione funziona ancora per te con LLVM? Sto cercando di farlo funzionare, ma il valore effettivo di FOO definito nelle macro del preprocessore delle impostazioni di compilazione non viene mai visualizzato. Potresti aggiornare la tua domanda con la soluzione che funziona per te?Saluti. – epologee

+1

Perché non solo '#define Helper (STR) @ # STR'? – tadeuzagallo

-1

Che errore stai vedendo esattamente? Questo tipo di cosa funziona come ci si aspetta:

#define kMyString @"MyString" 

[NSString stringWithFormat:@"macro: %@", kMyString]; 
+3

Il valore effettivo della stringa necessaria è il valore della macro preprocessore. Quindi non posso semplicemente inserire il valore nel codice come nel tuo esempio, deve venire dalla variabile FOO. – vagrant

26

Ecco una versione modificata della risposta di Adam Rosenfield con la semantica più chiare:

#define NSStringize_helper(x) #x 
#define NSStringize(x) @NSStringize_helper(x) 

Io lo uso per sostituire il codice come questo:

case OneEnumValue: name = @"OneEnumValue"; break; 
case AnotherEnumValue: name = @"AnotherEnumValue"; break; 

con questo:

#define case_for_type(type) case type: name = NSStringize(type); break 

case_for_type(OneEnumValue); 
case_for_type(AnotherEnumValue); 
1

È è necessario definire macro del preprocessore come,

FOO=\@\"BAR\" 

E lato utilizzare il codice simile,

[NSString stringWithFormat:@"macro: %@", FOO];