Есть ли разница при использовании {} pair или () pair при определении функционально-подобного макроса в C? - PullRequest
4 голосов
/ 26 апреля 2010

Например:

#define FOO(x)     (printf(x))

и

#define FOO(x)     {printf(x)}

Похоже, что обе жизнеспособны для предварительной обработки, но что лучше?

Ответы [ 4 ]

6 голосов
/ 26 апреля 2010

Если вы рассматриваете макрос как выражение, используйте форму ().

Если вы рассматриваете это как команду (а никогда не как выражение), тогда используйте форму {}. Или, скорее, используйте форму do{}while(0), поскольку она имеет меньше рисков замещения при использовании рядом с ключевыми словами, такими как if:

#define FOO(x) do {    \
    printf(x);         \
} while(0)
2 голосов
/ 26 апреля 2010

Круглые скобки () используются для обеспечения правильной оценки независимо от приоритета оператора, так что, надеюсь, вы не получите никаких неприятных побочных эффектов при развертывании макроса.

Скобки {} используются для того, чтобы сделать макрос оператором блока C, хотя канонический способ сделать это:

#define FOO(x) \
  do { \
    ... stuff ... \
  } while (0)

Обратите внимание, что gcc предоставляет расширение языка C, которое позволяет возвращать значение из блока - последнее вычисленное выражение будет значением, возвращаемым, если блок используется как часть выражения.

1 голос
/ 26 апреля 2010

Цель использования паренов в макросе - контролировать приоритет при раскрытии макроса.Подумайте:

#define X( a, b ) a * b

если макрос используется следующим образом

X( 1 + 2, 3 )

, нам, вероятно, хотелось бы, чтобы ответ был 9, но при расширении мы получаем:

1 + 2 * 3

давая нам 7. Чтобы избежать такого рода вещей, мы должны были написать макрос следующим образом:

#define X( a, b ) ((a) * (b))

Если приоритет не является проблемой, скобки любого типа не являются абсолютно необходимыми, хотя фигурные скобки могутв зависимости от семантики макросов - например, если вы хотите создать локальную переменную,

1 голос
/ 26 апреля 2010

Если вам когда-либо понадобится FOO(x) внутри выражения, тогда вы не можете использовать форму {}. Например:

result = FOO(some_variable);

или

if (FOO(some_variable))
...