0

假设我已经设置了一个宏扩展如下......

#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. ***")

OUTPUTDANGER *** Your boss is coming. *** THE COAST IS CLEAR ✅</p>

假设我有一个函数……</p>

NSString * WhosComing(void){ return @"*** Some fool. ***"; }

如何在不先将其分配给变量的情况下将此类函数的结果传递给宏,即

WARN(WhosComing())

ERRORexpected ')'

我搞砸了额外的括号,即

#define WARN((x))…… 或者……WARN_START (x) WARN_RESET但是……</p>

ERRORinvalid operands to binary expression, ETC。

以及尝试将 cuntion 作为指针或其他东西传递,即WARN(&WhosComing())无济于事。我确信这是可能的/直接的……但我没有计算机科学学位,所以我从来没有学过……对某人来说容易回答吗?

4

2 回答 2

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];
}
于 2013-04-01T17:58:11.090 回答
2

好吧,您不能在编译时插入函数的结果,因为显然函数的结果在执行之前不存在。但是你可以这样做:

#define WARN(x) [NSString stringWithFormat:@"%@ %@ %@", WARN_START, (x), WARN_RESET]

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

于 2013-04-01T17:52:34.047 回答