23

我在構建設置預處理宏值到目標C字符串文字

FOO=BAR 

該值欲按摩到一個Objective-C字符串文字可以被傳遞給方法中定義的預處理宏。下面的#define不起作用,但它應該表現出什麼,我想實現:

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

myMethodThatTakesAnNSString(FOOLITERAL); 

我希望,我只是缺少明顯的莫名其妙,但我似乎無法找到合適的預處理巫術得到什麼我需要。

回答

32

使用字符串化操作#做一個C串出的符號:這種類型的事情確實像您期望的工作。然而,由於預處理器的怪癖,你需要使用宏的兩個額外的層:

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

的原因額外的層是該字符串化操作符只能在宏的參數一起使用,不在其他令牌上。其次,如果宏的參數在宏的主體中應用了字符串化運算符,那麼該參數是而不是擴展爲另一個宏。因此,爲了確保FOO得到擴展,我們用另一個宏換行,這樣當STRINGIZE2得到擴展時,它也擴大FOO,因爲字符串化操作符不出現在宏的主體中。

+0

這樣做。我嘗試了雙重間接,但也有「@」作爲宏觀價值,似乎混淆了它。 一個小的區別是,第一行並不代表我的情況下,它不會檢索構建設置 的#define FOOVAL FOO 的#define STRINGIZE(X)#X 的#define STRINGIZE2(X)STRINGIZE(X) #define FOOLITERAL @ STRINGIZE2(FOOVAL) 實際上是爲我工作的。但你的回答讓我在那裏。 – vagrant

+0

嗨@vagrant。這個解決方案是否仍然適用於LLVM?我試圖讓這個工作,但在我的構建設置預處理器宏定義的FOO的實際價值從不出現。你可以用適合你的解決方案更新你的問題嗎?乾杯。 – epologee

+1

爲什麼不只是'#define Helper(STR)@#STR'? – tadeuzagallo

-1

你看到了什麼錯誤?

#define kMyString @"MyString" 

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

所需的串的實際值是預處理器宏的值。所以我不能只將值放入代碼中,它必須來自FOO變量。 – vagrant

26

這裏的亞當羅森菲爾德的回答修改後的版本與更清晰的語義:

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

我用它來這樣的替換代碼:

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

與此:

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

case_for_type(OneEnumValue); 
case_for_type(AnotherEnumValue); 
1

你需要定義預處理器宏,如

FOO=\@\"BAR\" 

而使用代碼側等,

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