预处理宏值到目标C字符串文字
问题描述:
我在构建设置预处理宏值到目标C字符串文字
FOO=BAR
该值欲按摩到一个Objective-C字符串文字可以被传递给方法中定义的预处理宏。下面的#define不起作用,但它应该表现出什么,我想实现:
#define FOOLITERAL @"FOO" //want FOOLITERAL to have the value of @"BAR"
myMethodThatTakesAnNSString(FOOLITERAL);
我希望,我只是缺少明显的莫名其妙,但我似乎无法找到合适的预处理巫术得到什么我需要。
答
使用字符串化操作#
做一个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
,因为字符串化操作符不出现在宏的主体中。
答
你看到了什么错误?
#define kMyString @"MyString"
[NSString stringWithFormat:@"macro: %@", kMyString];
+3
所需的串的实际值是预处理器宏的值。所以我不能只将值放入代码中,它必须来自FOO变量。 – vagrant
答
这里的亚当罗森菲尔德的回答修改后的版本与更清晰的语义:
#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);
答
你需要定义预处理器宏,如
FOO=\@\"BAR\"
而使用代码侧等,
[NSString stringWithFormat:@"macro: %@", FOO];
这样做。我尝试了双重间接,但也有“@”作为宏观价值,似乎混淆了它。 一个小的区别是,第一行并不代表我的情况下,它不会检索构建设置 的#define FOOVAL FOO 的#define STRINGIZE(X)#X 的#define STRINGIZE2(X)STRINGIZE(X) #define FOOLITERAL @ STRINGIZE2(FOOVAL) 实际上是为我工作的。但你的回答让我在那里。 – vagrant
嗨@vagrant。这个解决方案是否仍然适用于LLVM?我试图让这个工作,但在我的构建设置预处理器宏定义的FOO的实际价值从不出现。你可以用适合你的解决方案更新你的问题吗?干杯。 – epologee
为什么不只是'#define Helper(STR)@#STR'? – tadeuzagallo