Objective c 代码没有';不起作用,但等效代码起作用

Objective c 代码没有';不起作用,但等效代码起作用,objective-c,Objective C,那么我会: #define CLog( s, ... ) NSLog( @"%@", [NSString stringWithFormat:(s), ##__VA_ARGS__] ) #define PO(x) CLog(@#x ": %@", x) 工作 当然,它的一个简短版本是: NSString * hello =[NSString stringWithFormat:@"%@, %@",theCatalogData.id,@(theCatalogData.images.count)];

那么我会:

#define CLog( s, ... ) NSLog( @"%@", [NSString stringWithFormat:(s), ##__VA_ARGS__] )
#define PO(x) CLog(@#x ": %@", x)
工作

当然,它的一个简短版本是:

 NSString * hello =[NSString stringWithFormat:@"%@, %@",theCatalogData.id,@(theCatalogData.images.count)];
    PO(hello);
那不行。我想知道为什么


没有紧急情况。没问题。不管怎样,更长的等价物仍然有效。我只是想了解编译器是如何解析宏的,以了解为什么事情不起作用。

由于预处理器本身并不真正理解语法,因此包含逗号的宏参数将导致问题

在第二种情况下,由于参数在引号外包含两个逗号,编译器认为宏得到的是3个参数而不是一个,并且由于宏只接受一个参数,编译器会抱怨

与第二个案例类似的简化测试案例

PO([NSString stringWithFormat:@"%@, %@",theCatalogData.id,@(theCatalogData.images.count)]);
将扩大到,

#define TEST(a,b,c) a
TEST([d e:@"%@, %@", f, g])
这表明
a
参数仅包含第一个未加引号的逗号之前的所有字符


在您的例子中,您将测试宏定义为接受一个参数,并且由于预处理器将其视为3,编译将失败。

Xcode不会解析代码。编译器真是太棒了。你怎么知道宏将扩展成什么?@SharenEayrs我刚刚将上面的示例粘贴到一个名为
test.c
的文件中,然后从控制台窗口()运行
gcc-E test.c
。它会将预处理过的文件输出到控制台,这样你就可以直观地检查它。另外,你可以做你想做的事情,你只需要把你的参数用另一组括号括起来。所以像
宏([nsstringstringwithformat:@“%@-%@”,foo,bar])这样的东西就可以了。
[d e:@"%@, %@"