C Променливи макроси __VA_ARGS__ срещу ##__VA_ARGS__ в clang

Имам следните два макроса:

#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: Проблем 19141


person Jeffery Thomas    schedule 13.03.2014    source източник
comment
Като заобиколно решение, #define F3(...) F2(__VA_ARGS__), тогава използвайте F3 вместо F2. ;)   -  person augurar    schedule 14.03.2014


Отговори (1)


Изглежда ми, че препроцесорът не разширява вътрешното използване на макроса F2. Очевидно използването на ##__VA_ARGS__ е просто вмъкване на аргументите от външната употреба на F2 дословно и не извършване на по-нататъшно разширение.

Можете да накарате компилатора да обработи предварително кода и той ще ви покаже какво се е случило. cc -E -o foo.i foo.c

person Ken Thomases    schedule 14.03.2014