假设我已按如下方式设置宏扩展......
#define WARN_START @"DANGER"
#define WARN_RESET @"THE COAST IS CLEAR"
#define WARN(x) WARN_START x WARN_RESET
INPUT WARN(@"*** Your boss is coming. ***")
OUTPUT DANGER *** Your boss is coming. *** THE COAST IS CLEAR
✅
让我假设我有一个功能...
NSString * WhosComing(void){ return @"*** Some fool. ***"; }
如何将此类函数的结果传递给宏,而不先将其赋值给变量,即
WARN(WhosComing())
错误 expected ')'
我已经弄乱了额外的括号,即
#define WARN((x))
...。或者...... WARN_START (x) WARN_RESET
但是......
ERROR invalid operands to binary expression
等
以及尝试将cuntion作为指针或其他内容(即WARN(&WhosComing())
)传递无效。我确信这是可行的/直截了当的...但我没有CS学位,所以我从来没有学过如何......很容易回答某人?
答案 0 :(得分:3)
你不能用宏来做你正在尝试的事情。它是C语言(以及Objective-C,C ++)的一个特性,它在编译期间将相邻的字符串文字连接起来,并将Objective-C扩展为包含NSString
文字。
您的宏扩展为:
@"DANGER" @"*** Your boss is coming. ***" @"THE COAST IS CLEAR"
然后编译器将这3个文字连接成1。
然而传递你的功能,你得到:
@"DANGER" WhosComing() @"THE COAST IS CLEAR"
这是无效代码。
有各种解决方案;你可以使用一个真正的函数,如果真的担心函数调用的成本,可以内联它:
NS_INLINE NSString *WARN(NSString *msg)
{
return [NSString stringWithFormat:@"%@%@%@", WARN_START, msg, WARN_RESET];
}
答案 1 :(得分:2)
好吧,你不能在编译时插入函数的结果,因为很明显函数的结果在执行之前不存在。但你可以这样做:
#define WARN(x) [NSString stringWithFormat:@"%@ %@ %@", WARN_START, (x), WARN_RESET]
但这并不比一个功能更好,是吗?如果宏的参数是文字字符串,您可以按照您想要的方式编写它。但是由于参数的值在编译时甚至都不知道,所以在宏扩展阶段你可以用它做很多事情,因此发出一个表达式可以在运行时产生你想要的值,这几乎是你唯一的选择