【问题标题】:C Variadic Macros __VA_ARGS__ vs ##__VA_ARGS__ in clangC 可变参数宏 __VA_ARGS__ 与 ##__VA_ARGS__ 在 clang
【发布时间】:2014-03-13 15:27:01
【问题描述】:

我有以下两个宏:

#define F1(...) [NSString stringWithFormat:__VA_ARGS__]
#define F2(format, ...) [NSString stringWithFormat:(format), ##__VA_ARGS__]

当我嵌套它们时,F1 可以工作,但 F2 无法编译。

这段代码:

    F1(@"%@", F1(@"%@", @"a"));
    F2(@"%@", F2(@"%@", @"a"));

导致以下 clang 错误:

foo.m:51:15: warning: implicit declaration of function 'F2' is invalid in C99 [-Wimplicit-function-declaration]
    F2(@"%@", F2(@"%@", @"a"));
          ^
foo.m:18:64: note: expanded from macro 'F2'
#define F2(format, ...) [NSString stringWithFormat:(format), ##__VA_ARGS__]
                                                           ^
foo.m:51:15: warning: format specifies type 'id' but the argument has type 'int' [-Wformat]
    F2(@"%@", F2(@"%@", @"a"));
         ~~   ^~~~~~~~~~~~~~~
         %d
foo.m:18:64: note: expanded from macro 'F2'
#define F2(format, ...) [NSString stringWithFormat:(format), ##__VA_ARGS__]

注意F1没有警告或错误,只有F2有问题。

这里发生了什么:这是预期的行为还是 clang 中的错误?

更重要的是,我有没有办法调整 F2 以使其工作。我真的更喜欢 F2 的语法。


更新

按照@KenThomases 的建议,我跑了clang -E -o foo.i foo.m

# 1 "foo.m"
# 1 "<built-in>" 1
# 1 "<built-in>" 3
# 178 "<built-in>" 3
# 1 "<command line>" 1
# 1 "<built-in>" 2
# 1 "foo.m" 2



NSLog([NSString stringWithFormat:@"%@", [NSString stringWithFormat:@"%@", @"a"]]);
NSLog([NSString stringWithFormat:(@"%@"), F2(@"%@", @"a")]);

我将此作为缺陷提交给 llvm.org:Bug 19141

【问题讨论】:

  • 作为一种解决方法,#define F3(...) F2(__VA_ARGS__),然后使用F3 代替F2。 ;)

标签: c xcode macros clang variadic-macros


【解决方案1】:

在我看来,预处理器并未扩展 F2 宏的内部使用。显然##__VA_ARGS__的使用只是逐字插入外部使用F2的参数,并没有进行进一步的扩展。

你可以让编译器预处理代码,它会告诉你发生了什么。 cc -E -o foo.i foo.c

【讨论】:

    猜你喜欢
    • 2014-09-01
    • 2014-03-03
    • 2019-03-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-08-01
    • 1970-01-01
    • 2022-01-18
    相关资源
    最近更新 更多