如何将函数的结果作为Macro变量传递?

时间:2013-04-01 17:42:35

标签: objective-c c function pointers macros

假设我已按如下方式设置宏扩展......

#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学位,所以我从来没有学过如何......很容易回答某人?

2 个答案:

答案 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]

但这并不比一个功能更好,是吗?如果宏的参数是文字字符串,您可以按照您想要的方式编写它。但是由于参数的值在编译时甚至都不知道,所以在宏扩展阶段你可以用它做很多事情,因此发出一个表达式可以在运行时产生你想要的值,这几乎是你唯一的选择