Передача многопараметрической функции в макрос - PullRequest
1 голос
/ 11 июня 2009

Почему это не компилируется в VC 2005?

bool isTrue(bool, bool) { return true; }

void foo();

#define DO_IF(condition, ...) if (condition) foo(__VA_ARGS__);          

void run()
{
    DO_IF(isTrue(true, true)); // error C2143: syntax error : missing ')' before 'constant'
}

Выполнение этого через одни только выходы препроцессора:

bool isTrue(bool, bool) { return true; }

void foo();



void run()
{
    if (isTrue(true  true)) foo();; 
}

Обратите внимание на пропущенную запятую в предпоследней строке.

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

LOL! * * 1013

bool isTrue(bool, bool) { return true; }

void foo();

#define DO_IF(condition, ...) if (condition) { foo(__VA_ARGS__); }

void run()
{
    DO_IF(isTrue(true ,, true)); // ROTFL - This Compiles :)
}

Ответы [ 5 ]

3 голосов
/ 11 июня 2009

Макросы с неопределенным числом аргументов не существуют ни в стандарте C 1990 года, ни в текущем стандарте C ++. Я думаю, что они были введены в стандарт С 1999 года, и реализации были довольно медленными, чтобы принять изменения из этого стандарта. Они будут в готовящемся стандарте C ++ (который, я думаю, выйдет в следующем году).

Я не удосужился отследить соответствие C99 в Visual Studio, главным образом потому, что единственное, для чего я больше использую C, требует чрезвычайной переносимости, и я пока не могу этого добиться с C99. Однако вполне вероятно, что в VS 2005 не было частей C99, которые были в VS2008.

С другой стороны, возможно, вы компилировали программу как C ++. Проверьте свойства вашего компилятора.

1 голос
/ 11 июня 2009

Различные реализации препроцессора с жадностью разбирают запятые, обрабатывая их как разделители для макропараметров. Таким образом, CPP считает, что вы просите «DO_IF» выполнить замену с двумя параметрами: «isTrue (true» и «true)».

1 голос
/ 11 июня 2009

Запустите ваш код через CPP (препроцессор C), чтобы увидеть, какие замены CPP делает для вашего макроса.

Вы можете сделать это, вызвав cpp или предоставив компилятору параметр -E (если вы, конечно, используете gcc).

0 голосов
/ 11 июня 2009

Я думаю, что это должно сработать, разве что не должно быть ...

RETURN_IF(isTrue(b, !b));

и

RETURN_IF(isTrue(b,  b));
0 голосов
/ 11 июня 2009

Ваш код прекрасно компилируется в VS2008, если я изменю DO_IF на RETURN_IF. Однако это не должно изменить ничего, имеющего отношение к вашей ошибке.

Редактировать: Все еще компилируется без ошибок, даже после ваших изменений.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...