预处理器如何处理宏中的括号参数?

时间:2014-01-19 20:17:45

标签: objective-c macros

我有一个像这样的宏:

#define FBOX(x) [NSNumber numberWithFloat:x]

我听说过这些宏会由预处理器处理,其中source将被宏文本替换,但是当括号被抛入混合中时,这对我来说没有意义,因为我实际上从未说FBOX(x)。我说FBOX(1.0f)之类的东西。那么预处理器如何完全处理宏中的参数呢?

3 个答案:

答案 0 :(得分:2)

  

那么预处理器究竟是如何处理宏中的参数的呢?

基本宏替换是字符串替换,但它是语言识别

语言识别部分是宏的替换文本和宏的参数必须是(Objective-)C(++)中的整个标记;你不能包括一个没有收盘价的开盘双重报价。但是,这种意识在令牌级别停止,您可以定义宏,并传递宏参数,这些参数是不完整的代码块,甚至是无效的代码块 - 只要各个令牌有效。

作为语言意识的一部分,在预处理过程中也会删除注释和额外的空格。

字符串替换部分是宏“调用”仅由构成其定义的文本(单个标记)替换,并且定义中每个参数的使用被替换为调用中参数的文本。这一切都发生在之前编译器分析代码的语法。

所以在你的例子中:

#define FBOX(x) [NSNumber numberWithFloat:x]

然后是“电话”:

... FBOX(1.0f) ...

替换为:

... [NSNumber numberWithFloat:1.0f] ...

在编译器分析代码的语法之前。

要查看宏被标记化,我们可以将您的宏重新定义为:

#define FBOX(x) [NSNumber numberWithFloat:x.0f]

然后尝试:

... FBOX(1) ...

宏已成功替换,但编译器在分析语法时会产生错误,因为结果文本如下所示:

... [NSNumber numberWithFloat:1 .0f] ...

1& .0f两个标记,而不是单个浮点数。因此,编译器需要在]之后1并报告错误。

在Xcode中如果选择“产品:执行操作:预处理代码Xcode”将在预处理后显示文件的结果。

答案 1 :(得分:0)

它只是将x替换为1.0f,因此:

NSNumber *n = FBOX(1.0f);

变为:

NSNumber *n = [NSNumber numberWithFloat:1.0f];

然后将其呈现给编译器。

答案 2 :(得分:0)

假设:

#define FBOX(x) [NSNumber numberWithFloat:x]

使用FBOX(1.0f)将替换为:

[NSNumber numberWithFloat:1.0f]

在某种程度上,它类似于编写方法......

- (void)foo:(NSObject*)bar {
    // do stuff with bar
}

您不一定要将名为bar的变量传递给方法。你只是传入一个变量。然后该方法的主体将该变量用于该方法所做的任何事情,只是在您编写它时,您将其称为bar,因为您必须为它添加某种名称。