MSVC не разворачивает VA ARGS правильно

рассмотрим этот код:

#define F(x, ...) X = x and VA_ARGS = __VA_ARGS__
#define G(...) F(__VA_ARGS__)
F(1, 2, 3)
G(1, 2, 3)

ожидаемый результат X = 1 and VA_ARGS = 2, 3 для обоих макросов, и это то, что я получаю с GCC, однако MSVC расширяет это как:

X = 1 and VA_ARGS = 2, 3
X = 1, 2, 3 and VA_ARGS =

то есть __VA_ARGS__ расширяется как один аргумент, а не разбивается на несколько.

как-нибудь обойти это?

3 ответов


препроцессор MSVC, похоже, ведет себя совершенно иначе, чем стандартный спецификация.
Вероятно, поможет следующий обходной путь:

#define EXPAND( x ) x
#define F(x, ...) X = x and VA_ARGS = __VA_ARGS__
#define G(...) EXPAND( F(__VA_ARGS__) )

Я написал следующая проблема поддержки Microsoft:

следующая программа дает ошибку компиляции, потому что прекомпилятором расширяется __VA_ARGS__ неправильно:

#include <stdio.h>

#define A2(a1, a2) ((a1)+(a2))

#define A_VA(...) A2(__VA_ARGS__)

int main(int argc, char *argv[])
{
    printf("%d\n", A_VA(1, 2));
    return 0;
}

препроцессор расширяет printf до: printf ("%d\n", ((1, 2)+()));

вместо printf ("%d\n", ((1)+(2)));

Я получил следующий неудовлетворительный ответ от команды компилятора Microsoft разработчик:

Hi: компилятор Visual C++ в этом случае ведет себя правильно. Если вы объедините правило, которое маркеры, которые соответствуют '..."при вызове макроса inital объединяются в единую сущность (16.3/p12) с правилом, что под-макросы расширяются перед заменой аргумента (16.3.1 / p1), тогда в этом случае компилятор считает, что A2 вызывается с одним аргументом: отсюда сообщение об ошибке.


какую версию MSVC вы используете? Вам понадобится Visual C++ 2010.

__VA_ARGS__ был впервые представлен C99. MSVC никогда не пытался поддерживать C99, поэтому поддержка не была добавлена.

Теперь, однако, __VA_ARGS__ входит в новый стандарт C++, C++2011 (ранее известный как C++0x), который Microsoft, по-видимому, планирует поддерживать, поэтому он поддерживается в последних версиях MSVC.

кстати, вам нужно будет использовать .cpp суффикс к исходному файлу получить эту поддержку. MSVC не обновлял свой интерфейс C в течение длительного времени.