2010-01-16 3 views
8

Я заметил, что иногда, C макросы записываются как-то вроде этого:Дополнительная информация о `({});` in C?

#define foo(bar) ({ ++bar; }) 

После нескольких экспериментов я обнаружил, что:

  1. ({}); компилируется, но ничего не делают. (Как и ожидалось.)
  2. Оставив ошибку ;, вы получите синтаксическую ошибку. Побочным эффектом этого является то, что foo() выглядит как функция в вашем коде. (Хотя, если вы оставите точку с запятой выключенной, ошибка не очень полезна для диагностики проблемы!)
  3. return ({}); жалуется, что значение void не игнорируется, как если бы я попытался использовать функцию void.

Это просто, чтобы разработчики добавляли точку с запятой в свои макросы или у нее была другая цель? Я пробовал Google, но он терпел неудачу с пунктуацией. Есть ли имя для этого?

ответ

8

Это расширение GNU под названием statement expressions.

При объявлении макросов в стандартном C вы часто видите циклы do...while(0), используемые для аналогичных целей (т. Е. Создание области блока). Выражение оператора превосходит петлей, потому что оно может вернуть значение. Если вы хотите сделать что-то подобное в стандарте C, вам придется определить дополнительную функцию и потерять удобство лексического охвата.

2

() - это выражение. ({code; code;}) является составным выражением внутри выражения. Это расширение GNU C.

http://gcc.gnu.org/onlinedocs/gcc-2.95.3/gcc_4.html

EDIT: ничего себе, я получил эту ссылку от Google и не заметил, это было для GCC 2.95 на первом. Древний!

+0

Древний - но синтаксис по-прежнему поддерживается в 4.4.2. –

3

Замечательная вещь в выражениях высказываний (если есть классная вещь) заключается в том, что последнее выражение является результатом выражения.

#define foo(bar) ({ ++bar; 3.1415927; }) 

int i = 0; 
float pi = foo(i); 
Смежные вопросы