Зачем кому-то определять макрос C с неиспользованными аргументами / параметрами? - PullRequest
3 голосов
/ 02 июля 2010

Я просматривал какой-то код и наткнулся на это определение макроса

#define D(x) do { } while (0)

И он использовался в коде, подобном этому,

D(("couldn't identify user %s", user));

Я запустил код, и этот конкретныйлиния ничего не делаетИтак, почему кто-то может определять макрос таким образом?

Если вам интересно, этот макрос определен в заголовочном файле _pam_macros.h.

Ответы [ 2 ]

8 голосов
/ 02 июля 2010

Скорее всего, D для отладки, а в другом месте есть #ifdef, которая делает его более полезным, если включена отладка, например, выводит сообщение или записывает его в файл. Цикл do/while предназначен для того, чтобы в конце он требовал точку с запятой, поэтому пользователь может назвать его как D(...); вместо D(...) (см. этот пост )

0 голосов
/ 06 мая 2016

Это сделано для того, чтобы, если вы забыли добавить;в конце макроса он вызывает ошибку при компиляции, как если бы это была функция.

Если вы сделали этот (допустимый бесполезный) макрос:

#define DBG(x,y) printf ("Debug output %d\n", x); printf ("  %d\n", x+y); 

вы можетевызовите макрос следующим образом:

void someFun ()
{
  DBG(10,0)
  DBG(11,40)
}

И он будет прекрасно скомпилирован.

do {...} while (0) заставляет вас включить;в конце, в случае, если макрос позже превращается в функцию - что часто случается.Когда это изменение будет сделано, внезапно вы сможете исправить тысячи синтаксических ошибок.Я бы это определил так:

#define DBG(x,y)                   \
do                                 \
{                                  \
  printf ("Debug output %d\n", x); \
  printf ("  %d\n", x+y);          \
} while (0)

Теперь вы должны включить;в конце макроса.Помните, что макросы буквально заменяют код на этапе препроцессора.

Теперь рассмотрим, что произойдет, если вы сделаете это с обоими макросами:

if (x==y)
  DBG(x,y);

Всегда будет выводиться сумма x иу, независимо от того, что вычисляется, если вы использовали первый показанный макрос.

Вы, вероятно, думаете, что это исправит это:

#define DBG(x,y) {printf ("Debug output %d\n", x); printf ("  %d\n", x+y);} 

И это будет, но вывернулись к возможности забыть ';'снова.

Чистый код не обязательно хороший код, но отличный код, написанный как мусор, заставит вас думать, что код - отстой.Вырабатывайте хорошие привычки, потому что через 5 месяцев вам, возможно, придется вытащить какой-то код, с которым, как вы думали, вы покончили, и вы возненавидите свое прежнее «я» из-за того, что вас обманывают.макрос не был превращен в функцию, он был просто удален или никогда не заполнялся.

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