#c #macros #parentheses
#c #макросы #круглые скобки
Вопрос:
KdPrint(("Enter HelloWDMAddDevicen"));
В чем причина для этого?
Ответ №1:
Это значит, что вы можете передать весь список аргументов макросу и заставить его передать его функции, которая принимает переменное количество аргументов.
Я бы поспорил на что угодно, что определение этого макроса является:
#if DEBUG /* or something like it */
#define KdPrint(args) (printf args)
#else
#define KdPrint(args) /* empty */
#endif
Или аналогично какой-либо другой функции, которая работает точно так же, как printf .
Если бы это было определено как printf (args), тогда вы могли бы передать только один строковый аргумент, потому что аргумент макроса не может содержать запятую, которая не находится внутри вложенной круглой скобки.
Комментарии:
1. Вероятно, вы правы! Но я думаю, что тот, кто написал этот макрос, плохо справляется с работой. Он должен был заключить в скобки ‘аргументы’.
2. Нет, дело в том, что аргументов может быть несколько с запятой, поэтому они должны заключаться в круглые скобки вне макроса.
3. GCC поддерживает переменные макросы , поэтому, если вы можете быть уверены, что код всегда будет скомпилирован с помощью GCC, вы можете
#define KdPrint(...) (printf __VA_ARGS__)
.4. Поддержка переменных макросов — это не просто GCC, это стандарт C99 и C 11 .
Ответ №2:
Это приводит к тому, что все, что находится внутри скобок, обрабатывается как отдельный параметр макроса. В показанном примере это может допускать переменные типы параметров:
KdPrint(( "My info is %sn", "my name" ));
А также
KdPrint(( "fn %s ln %sn", "my", "name" ));
Ответ №3:
Если рассматриваемый макрос не был хорошо написан с использованием круглых скобок, это может быть необходимо из-за приоритета оператора. Возьмем, к примеру, этот макрос:
#define MY_MACRO(a) a * 11
Ну, если вы сделали это:
int b = MY_MACRO(1 2);
b
вместо значения 33, как должно быть, на самом деле было бы заменено на int b = 1 2 * 11
, которое равно 23, а не 33. Однако, если ваш макрос написан не так (без круглых скобок вокруг a
), то в нем нет необходимости.
Комментарии:
1. Несмотря на проницательность в отношении ошибок в макросах, если бы это действительно было проблемой, KdPrint поместил бы скобки внутри самого макроса. Гораздо более вероятно, что а) ему нужно передать все параметры функции, которая принимает переменное количество аргументов, или б) он пытается быть совместимым с препроцессорами, которые не поддерживают VA_ARGS , что означает, что вы должны передавать все аргументы как один аргумент макроса, пока они не достигнут уровня функции.
Ответ №4:
Если это то, KdPrint()
о чем вы говорите, то это потому, что вы можете использовать KdPrint()
макрос с аргументами формата, и это не макрос переменной длины.
Например, вы можете сделать:
KdPrint(("The answer is %dn", 42));
и так далее.
Ответ №5:
Для вашего конкретного примера я не могу вам сказать, потому что я не знаю, что такое XdPrint.
Но в более общем случае это потому, что мне просто нравится искать и заменять макрос. Предположим, у вас есть:
#define MULT(a,b) (a*b)
Если вы вызовете MULT(1 1, 2 2)
, это станет 1 1*2 2
и приведет к 5
вместо 8
того, что вы ожидаете. Выполнение MULT((1 1), (2 2))
дало бы вам ожидаемый результат. Вот почему вам нужно удвоить скобки.